'통신'에 해당되는 글 4건

  1. 2009.12.18 connect()
  2. 2009.12.15 socket()
  3. 2009.06.23 WinIO
  4. 2008.04.16 CVI 시리얼 통신 예제
2009. 12. 18. 09:30

connect()



TCP 기반의 클라이언트 프로그램의 구현순서는 간단하다
  1. 소켓 생성
  2. 연결 요청
  3. 데이터 송수신
  4. 연결 종료
TCP 기반의 서버 프로그램과 비교해 볼 때 소켓 생성, 데이터 송수신, 연결 종료는 공통되는 부분이고, 다른 부분은 단지 '연결 요청'이다.

서버 프로그램에서 연결 요청 대기를 하고 있을 때 비로소 클라이언트 프로그램에서는 연결 요청을 할 수 있는 것이다. 연결 요청은 'connect()' 함수를 사용한다.

#include <sys/types.h>
#include <sys/socket.h>

int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);

  • sockfd - 통신을 위해 생성한 소켓의 파일 디스크립터
  • serv_addr - 연결 요청을 할 서버의 주소정보를 가진 구조체 변수의 포인터
  • addrlen - 연결 요청을 할 서버의 주소정보를 가진 구조체 변수의 크기

connect() 예제
...
int sock;
struct sockaddr_in serv_addr;
...
// 클라이언트 소켓 생성
sock = socket(PF_INET, SOCK_STREAM, 0);       
...
// connect()로 연결 요청
if(connect(sock, (struct sockaddr* ) &serv_addr, sizeof(serv_addr)) == -1)
...








'Programmings > TCP/IP socket programming' 카테고리의 다른 글

listen() and accept()  (0) 2009.12.16
bind()  (0) 2009.12.15
socket()  (0) 2009.12.15
2009. 12. 15. 10:02

socket()



통신을 하기 위해선 소켓을 생성해야 한다. 소켓은 통신을 위한 엔드포인트 정도로 생각하면 될 듯 하다.
소켓을 생성하기 위해서 socket() 이란 함수를 사용한다. socket()를 통해 시스템 내부적으론 소켓을 생성하고, 생성된 소켓을 조작하기 위한 파일 디스크립터를 리턴한다.

#include <sys/types.h>
#include <sys/socket.h>

int socket (int domain, int type, int protocol);

  • domain - 통신을 하기 위해 사용할 프로토콜 체계(Protocol Family)
  • type - 소켓에서 사용하게 될 데이터 전송 타입
  • protocol - 통신을 하기 위한 프로토콜
  • 리턴값 - 성공 시 int형 파일 디스크립터, 실패 시 -1 리턴

일반적으로 아래와 같이 TCP socket 또는 UDP socket 를 생성하여 사용하게 된다.
...
int tcp_sock, udp_sock;
tcp_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
...

리턴값으로 파일 디스크립터를 받게 되는데, 리눅스에서 현재 사용하고 있는 디스크립터(0, 1, 2 이외의 )가 있다면 그 다음 숫자부터 차례로 디스크립더를 리턴받게 된다.

'Programmings > TCP/IP socket programming' 카테고리의 다른 글

connect()  (0) 2009.12.18
listen() and accept()  (0) 2009.12.16
bind()  (0) 2009.12.15
2009. 6. 23. 09:45

WinIO



WinIO 는 윈도우즈(9x, NT, 2000, XP 등) 보호모드상에서 포트나 메모리의 직접적인 접근을 가능하도록 Yariv Kaplan이라는 사람이 만들어 놓은 라이브러리로 오픈소스이다. WinIO는 드라이버의 소스까지 공개되어 있어 누구나 분석하거나 사용할 수 있고, http://www.internals.com 에 방문하게 되면 얻을 수 있다.
사용법이라든지 도움말, 그리고 간단한 예제 프로그램이 같이 있어 사용하는데 문제는 없을 듯 하다.


원하는 포트를 사용하여 어플리케이션과 디바이스 드라이버간의 통신을 위해 사용할 수 있다. 특시 60, 64 포트를 이용하여 키보드 제어를 위해서도 사용을 하기도 한다.

기타 WinIO 에 대한 자료는 google을 검색하면 수도 없이 나올 것이다.
필요한 부분은 알아서 자알 찾으면 될 듯.. ㅎ


2008. 4. 16. 19:25

CVI 시리얼 통신 예제



간단한 '시리얼 통신프로그램''LabWindows/CVI'로 구현하는 방법에 대해 알아보려 한다.

LabWindows/CVI에서 제공하는 Sample RS232예제를 보고 하려니 쫌 답답한 면도 있고.. 약간 복잡(?)한것 같아 일단 접는다. ㅋ
'CVI 정보나눔'이라는 한글 CVI관련 사이트의 예제 프로그램을 간단히 분석해보려 한다.

RS-232통신이라고 하지만.. 간단한 예제라 그런지 생각보다 단순하다.

'CVI 정보나눔'에서는 다른 프로그램과 연동하여 그 프로그램의 정보를 받아오는 역할을 하지만, 본인은 간단히 루프백하여 전송한 데이터를 다시 받아오는 형식으로 진행한다. 그게 간단하니깐...
프로그램을 설명하자면, RS-232 Port에서 포트를 선택하고, Write 에서 전송할 데이터를 입력하고 Query버튼을 클릭하면, 전송한 데이터가 Read로 다시 리턴되는 프로그램이다.
사용자 삽입 이미지

대충의 'uir'을 위의 화면과 같이 작성한다. 보기 좋게 속성 값과 함수의 값도 설정하고...
다 대충 대충 해도 Query버튼에 관련된 세팅은 대충하면 안된다. RS-232 통신하는데 가장 중요한 부분이므로..

본인의 경우 Query버튼의 속성을 아래 그림과 같이 Callback Function을 cmdQuery라고 정해 주었다. 사실... CVI정보나눔에서 이리 되어 있어 따라한거긴 하지만... -_-
사용자 삽입 이미지

cmdQuery 콜백함수의 내용은 아래와 같다.
int CVICALLBACK cmdQuery (int panel, int control, int event,
void *callbackData, int eventData1, int eventData2)
{
switch (event) {
case EVENT_COMMIT:
{
int port, RTCount;

// 쓰기 버퍼관련 변수들..
char WriteBuffer[256];
int length;
int TermChar; // 전송하기 전에 덧붙일 Term.Char방법
// 0:None, 1:CR(0x0D), 2:LF(0x0A), 3:CR+LF

// 읽기 버퍼관련 변수들..
char ReadBuffer[10000];

// 1. Port를 Open하고, Configure합니다.
GetCtrlVal (panel, PANEL_ringRESOURCE, &port);
if(!OpenComConfig (port, "", 9600, 0, 8, 2, 512, 512) ) {
SetComTime (port, 2000);

// 2. 장치 포트로 보낼 데이터를 읽어옵니다.
GetCtrlVal (panel, PANEL_strWriteBuffer, WriteBuffer);
GetCtrlVal (panel, PANEL_ringTermChar, &TermChar);

// 3. Termination character를 덧붙여서 송신합니다.
switch(TermChar) {
case 1:
strcat(WriteBuffer, "\015"); // CR(0x0D)는 8진수로 015
break;
case 2:
strcat(WriteBuffer, "\012"); // LF(0x0A)는 8진수로 012
break;
case 3:
strcat(WriteBuffer, "\015\012");
break;
}
length = strlen(WriteBuffer);
ComWrt (port, WriteBuffer, length);

// 4. 장치 포트로부터 데이터를 읽어옵니다.
ReadBuffer[0] = '\0';
RTCount = ComRdTerm (port, ReadBuffer, 50, 0x0A);
ReadBuffer[RTCount] = '\0';
SetCtrlVal(panel, PANEL_strReadBuffer, ReadBuffer);

// 5. 포트를 닫습니다.
CloseCom (port);
}
}
break;
}
return 0;
}

일반적인 통신 프로그래밍과 얼추 비슷한것 같다.
통신할 장치(Device)를 열고, 읽고, 쓰고, 통신한 장치를 닫고... 등..

LabWindows/CVI에서의 시리얼 통신에 관련된 부분은 NI의 웹페이지에서도 찾아볼 수 있다.
LabWindows/CVI Serial Communication Serial Communication Programming(http://www.ni.com/support/cvi/serlprog.htm)

위의 링크를 따라가면
  • Opening and Closing COM Ports
  • Writing to COM Port
  • Reading from COM Port
  • Using InstallComCallback with Serial Reads
등에 관련된 정보를 얻을 수 있다.