Server
- 1_server
: 기본 서버 구조#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> int main() { // 1. socket 생성 int sock = socket(PF_INET, SOCK_STREAM, 0); // 2. bind() : 소켓 주소 지정 struct sockaddr_in saddr = {0, }; saddr.sin_family = AF_INET; saddr.sin_port = htons(4000); // 연결을 받을 주소 saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); bind(sock, (struct sockaddr*)&saddr, sizeof saddr); // 3. 연결 대기 상태로 만든다. : listen listen(sock, 5); // 4. 클라이언트 요청 수락 : accept struct sockaddr_in caddr = {0, }; socklen_t clen = sizeof(caddr); int csock = accept(sock, (struct sockaddr*)&caddr, &clen); printf("연결이 수립되었습니다.\n"); close(csock); close(sock); }
- 2_server
: 여러 클라이언트 받아들이기
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> int main() { int sock = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in saddr = {0, }; saddr.sin_family = AF_INET; saddr.sin_port = htons(4000); // saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 문제점 : 127.0.0.1로 오는 연결만 받을 수 있다. // 해결방법 : INADDR_ANY(0.0.0.0); saddr.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0 bind(sock, (struct sockaddr*)&saddr, sizeof saddr); listen(sock, 5); while (1) { struct sockaddr_in caddr = {0, }; socklen_t clen = sizeof(caddr); int csock = accept(sock, (struct sockaddr*)&caddr, &clen); char* cip = inet_ntoa(caddr.sin_addr); printf("Connected from %s\n", cip); close(csock); } close(sock); }
- 3_server
: bind(): Address already in use 해결
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> // 1. bind() : Adress already in use // 먼저 연결을 종료한 측의 소켓은 유지되어야 한다. - TIME_WAIT // => TIME_WAIT 상태가 종료 되기 이전에 해당 포트로 서버를 바인드 // 하는 것이 불가능하다. // 2. TIME_WAIT : 같은 포트의 연결을 손상 시킬 수 있다. // 3. 클라이언트 포트는 동일한 포트로 바인딩 되지 않는다. // 4. 최신 네트워크 커널의 구현은 SYN의 시퀀스 번호가 TIME-WAIT 상태의 // 연결로부터 마지막 시퀀스 번호보다 클 경우에만 연결을 허용한다. // 5. TIME_WAIT은 먼저 연결을 종료한 쪽에서 발생한다. // 클라이언트는 포트가 변경되기 때문에 문제가 없다. int main() { int sock = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in saddr = {0, }; saddr.sin_family = AF_INET; saddr.sin_port = htons(4000); saddr.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0 //---------------- // 6. 해결방법 // 서버는 약속된 포트로부터 연결을 받아야 하므로 // 반드시 주소를 재할당 할 수 있도록 변경해주어야 한다. int option = true; socklen_t optlen = sizeof(option); setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &option, optlen); //----------------- int ret = bind(sock, (struct sockaddr*)&saddr, sizeof saddr); if (ret == -1) { perror("bind()"); return -1; } listen(sock, 5); struct sockaddr_in caddr = {0, }; socklen_t clen = sizeof(caddr); int csock = accept(sock, (struct sockaddr*)&caddr, &clen); close(csock); close(sock); }
Client
- 1_client ~ 2_client
: 기본 클라이언트 구조
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <string.h> int main() { int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in addr = {0, }; addr.sin_family = AF_INET; addr.sin_port = htons(4000); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); int ret = connect(sd, (struct sockaddr*)&addr, sizeof(addr)); if (ret == -1) { perror("connect()"); return -1; } printf("Connection succeed!!\n"); close(sd); }
- 3_client
: TIME_WAIT 문제 확인
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <errno.h> #include <string.h> int main() { int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); struct sockaddr_in addr = {0, }; addr.sin_family = AF_INET; addr.sin_port = htons(4000); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); int ret = connect(sd, (struct sockaddr*)&addr, sizeof(addr)); if (ret == -1) { perror("connect()"); return -1; } printf("Connection succeed!!\n"); sleep(5); close(sd); }
'Programing > Server Model' 카테고리의 다른 글
서버 모델 - I/O 모델 개요 (0) | 2016.02.22 |
---|---|
서버 모델 - 리눅스 소켓 프로그래밍(3) (0) | 2016.02.22 |
서버 모델 - 리눅스 소켓 프로그래밍(2) (0) | 2016.02.18 |
서버 모델 - 소켓 프로그래밍 (0) | 2016.02.18 |
서버 모델 - 기초 (0) | 2016.02.16 |