• 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);
    }
    
    


+ Recent posts