소켓 통신
소켓 통신이 성공할경우
send와 recv 대신에 write , read 함수를 이용하여 문자를 주고 받음
write(iClient1,"wellcome",7);
read(iSock,ucBuff,sizeof(ucBuff));
\
결과
ucBuff[250]이므로 글자만 출력하기위해선read함수는 글자수만큼 반환함
-1하는 이유는 read함수는 엔터값을 입력 받으므로 iret-1을 해준다.
포트를 맞춰서 다른 컴퓨터에서도 통신이 가능
파일 전송
도스모드에서
ftp 192.168.10.250
bin
put "해당파일"
예제
27_2.c
보기 접기
#include < stdio.h >
#include < string.h > #include < sys/types.h > #include < sys/socket.h > #include < netinet/in.h > #include < arpa/inet.h > #include < unistd.h > #define PORT 4080 #define BUFSIZE 1024 int main( int argc, char *argv[]) { int sockfd; //소켓 struct sockaddr_in servAddr; char sendBuffer[BUFSIZE]; char recvBuffer[BUFSIZE]; int recvLen; if (argc! = 2 ) { fprintf(stderr, "Usage: %s IP_address\n" ,argv[ 0 ]); exit( 1 ); } if ((sockfd = socket(AF_INET,SOCK_STREAM, 0 )) = = - 1 ) { perror( "sock failed" ); exit( 1 ); } memset( & servAddr, 0 , sizeof (servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(argv[ 1 ]); servAddr.sin_port = htons(PORT); if (connect(sockfd, ( struct sockaddr *) & servAddr, sizeof (servAddr)) = = - 1 ) { perror( "connect failed" ); exit( 1 ); } //quit를 입력받을 때까지 반복 while ( 1 ) { printf( "Input sending message = = > " ); fgets(sendBuffer, BUFSIZE, stdin); if (!strncmp(sendBuffer, "quit" , 4 )); { break ; } if (send(sockfd, sendBuffer, strlen(sendBuffer), 0 ) ! = strlen(sendBuffer)) { perror( "send failed" ); exit( 1 ); } if ((recvLen = recv(sockfd,recvBuffer,BUFSIZE- 1 , 0 )) < = 0 ) { perror( "recv failed" ); exit( 1 ); } recvBuffer[recvLen] = '\0' ; printf( "received: %s\n" , recvBuffer); } close(sockfd); return 0 ; }
접기
27_1.c
보기 접기
#include < stdio.h >
#include < string.h > #include < sys/types.h > #include < sys/socket.h > #include < netinet/in.h > #include < arpa/inet.h > #include < unistd.h > #define PORT 4080 // 포트번호 #define MAXPENDING 5 // 클라이언트 요구가 대기하는 큐의 크기 #define BUFSIZE 1024 //recvBuffer의 크기 int main() { int servSockfd; //소켓 int clntSockfd; //accept소켓 번호 저장 struct sockaddr_in servAddr; struct sockaddr_in clntAddr; char recvBuffer[BUFSIZE]; int clntLen; int recvLen; //수신된 데이터 저장 if ((servSockfd = socket(AF_INET, SOCK_STREAM, 0 )) = = - 1 ) { perror( "sock failed" ); exit( 1 ); } memset( & servAddr, 0 , sizeof (servAddr)); //servAddr을 0으로 초기화 servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(PORT); //소켓에 주소 정보 연결 if (bind(servSockfd, ( struct sockaddr *) & servAddr, sizeof (servAddr)) = = - 1 ) { perror( "bind failed" ); exit( 1 ); } //클라이언트 요청 기다림 if (listen(servSockfd, MAXPENDING) = = - 1 ) { perror( "listen failed" ); exit( 1 ); } //무한반복 while ( 1 ) { clntLen = sizeof (clntAddr); //클라이언트 요청을 받아 들임 if ((clntSockfd = accept(servSockfd, ( struct sockaddr *) & clntAddr, & clntLen)) = = - 1 ) { perror( "accept failed" ); exit( 1 ); } //한 클아이언트에 대해 반복 while ( 1 ) { //소켓으로 들어오는 데이터를 받아 recvBuffer에 저장 if ((recvLen = recv(clntSockfd,recvBuffer,BUFSIZE- 1 , 0 )) = = - 1 ) { perror( "recv failed" ); exit( 1 ); } //클라이언트가 연결을 끊으면 recv는 0을 반환 if (recvLen = = 0 ) { break ; } recvBuffer[recvLen] = '\0' ; //받을 데이터를 출력 printf( "Received: %s\n" , recvBuffer); //받을 데이터를 클라이언트에게 보냄 if (send(clntSockfd, recvBuffer, recvLen, 0 ) ! = recvLen) { perror( "send failed" ); exit( 1 ); } } close(clntSockfd); } return 0 ; }
접기
예제는 1:1 통신이다.
1:다 통신이 필요함
단점
그러나 C언어는 순차지향 언어 이므로 1:다 통신을 구현하기가 곤란함
이를 보완한게 3가지 방법이 있는데
멀티 프로세스 멀티 쓰레드 select 함수 이다.
포트폴리오
도서관리 원라인 128 2560 채팅 packet analyzer(packet snipping)