Chapter 04. TCP Server/Client
Basic structure and principle of TCP server/client Goal Basic structure and principle of TCP server/client Socket system call for TCP application Understanding application protocol
TCP server/client operation (1/6) TCP server/client example GET / HTTP/1.1 Accept: image/gif, ... <HTML> <HEAD>...</HEAD>... Web server Web client Web client
TCP server/client operation (2/6) TCP client listen accept recv send connect network
TCP server/client operation (3/6) TCP server/client socket calls (cont’d) - bind : to assign a name to an unnamed socket. - listen: to indicate that it is willing to receive connections. - connect: to establish a connection with a server - send: to send data to peer side - accept: to accept the connection request from client - recv: to receive the data that client sent
TCP server/client operation(4/6) TCP server/client operation principle TCP server waiting TCP server TCP clients #1 Client connecting
TCP server/client operation(5/6) TCP server/client operation principle (cont’d) TCP server TCP client #1 Comm. waiting TCP server TCP client #1 client #2 Comm. waiting
TCP server/client operation(6/6) TCP server/client operation principle (cont’d) TCP server TCP client #1 waiting client #n . . .
TCP server/client example Code Example(TCPServer.cpp, TCPClient.cpp) TCP client TCP server fgets() send() printf() recv()
TCP server/client analysis (1/2) Socket requires three components ① protocol Defined by Socket() system call ② local IP address and port number Server or client side ③ remote IP address and port number
TCP server/client analysis (2/2) Socket data structure server local IP addr. Local port num. Remote IP addr. Remote port num. client application OS network • • •
Socket call for TCP server (1/8) TCP server side socket() bind() recv() send() closesocket() TCP server TCP client connect() listen() accept() network
Socket call for TCP server (2/8) bind() Assign a name to an unnamed socket Define IP address and port number of server side int bind ( SOCKET s, const struct sockaddr* name, int namelen ) ; success: 0, fail: SOCKET_ERROR
Socket call for TCP server (3/8) bind() example 050 SOCKADDR_IN serveraddr; 051 ZeroMemory(&serveraddr, sizeof(serveraddr)); 052 serveraddr.sin_family = AF_INET; 053 serveraddr.sin_port = htons(9000); 054 serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 055 retval = bind(listen_sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr)); 056 if(retval == SOCKET_ERROR) err_quit("bind()");
Socket call for TCP server (4/8) listen() transit TCP port state to LISTENING state - ready to receive connections. int listen ( SOCKET s, int backlog ) ; success: 0, fail: SOCKET_ERROR
Socket call for TCP server (5/8) listen() example 059 retval = listen(listen_sock, SOMAXCONN); 060 if(retval == SOCKET_ERROR) err_quit("listen()");
Socket call for TCP server (6/8) accept() accept the connection request from client tell the IP address and port number of client SOCKET accept ( SOCKET s, struct sockaddr* addr, int* addrlen ) ; success: new socket, fail: INVALID_SOCKET
Socket call for TCP server (7/8) accept() example 062 // variables for data communiction 063 SOCKET client_sock; 064 SOCKADDR_IN clientaddr; 065 int addrlen; ... 068 while(1){ 069 // accept() 070 addrlen = sizeof(clientaddr); 071 client_sock = accept(listen_sock, (SOCKADDR *)&clientaddr, &addrlen); 072 if(client_sock == INVALID_SOCKET){ 073 err_display("accept()"); 074 continue; 075 }
Socket call for TCP server (8/8) accept() example (cont’d) 076 printf("\n[TCP server] client connection: IP addr=%s, port num=%d\n", 077 inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); 078 079 // data comm with client 080 while(1){ ... 101 } 102 103 // closesocket() 104 closesocket(client_sock); 105 printf("[TCP server] client exit: IP addr=%s, port num=%d\n", 106 inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); 107 }
Socket call for TCP client (1/3) TCP client side TCP server TCP client socket() socket() bind() listen() network accept() connect() recv() send() send() recv() closesocket() closesocket()
Socket call for TCP client (2/3) connect() to establish a connection with a server int connect ( SOCKET s, const struct sockaddr* name, int namelen ) ; success: 0, fail: SOCKET_ERROR
Socket call for TCP client (3/3) connect() example 070 SOCKADDR_IN serveraddr; 071 serveraddr.sin_family = AF_INET; 072 serveraddr.sin_port = htons(9000); 073 serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 074 retval = connect(sock, (SOCKADDR *)&serveraddr, sizeof(serveraddr)); 075 if(retval == SOCKET_ERROR) err_quit("connect()");
Data transfer socket call (1/10) Socket data structure server Local IP addr Local port num Remote IP addr Remote port num client application OS network • • • Recv buffer Send buffer
Data transfer socket call (2/10) send() 함수 Data transfer to peer side int send ( SOCKET s, const char* buf, int len, int flags ); success: num of sent bytes, fail: SOCKET_ERROR
Data transfer socket call (3/10) recv() Data receving from peer side int recv ( SOCKET s, char* buf, int len, int flags ); success: num of received bytes or 0(the remote side has closed the connection ), fail: SOCKET_ERROR
Data transfer socket call (4/10) recvn() function 037 int recvn(SOCKET s, char *buf, int len, int flags) 038 { 039 int received; 040 char *ptr = buf; 041 int left = len; 042 043 while(left > 0){ 044 received = recv(s, ptr, left, flags); 045 if(received == SOCKET_ERROR) 046 return SOCKET_ERROR; 047 else if(received == 0) 048 break; 049 left -= received; 050 ptr += received; 051 } 052 053 return (len - left); 054 }
Data transfer socket call (5/10) recvn() function principle buf ptr left len 읽은 데이터
Data transfer socket call (6/10) Data send/recv example – TCP client 078 char buf[BUFSIZE+1]; 079 int len; ... 082 while(1){ 083 // data input 084 ZeroMemory(buf, sizeof(buf)); 085 printf("\n[sending data] "); 086 if(fgets(buf, BUFSIZE+1, stdin) == NULL) 087 break; 088 089 // '\n' char delete 090 len = strlen(buf); 091 if(buf[len-1] == '\n') 092 buf[len-1] = '\0'; 093 if(strlen(buf) == 0) 094 break;
Data transfer socket call (7/10) Data send/recv example – TCP client (cont’d) 096 // data sending 097 retval = send(sock, buf, strlen(buf), 0); 098 if(retval == SOCKET_ERROR){ 099 err_display("send()"); 100 break; 101 } 102 printf("[TCP client] %d bytes sent...\n", retval); 103 104 // data receiving 105 retval = recvn(sock, buf, retval, 0); 106 if(retval == SOCKET_ERROR){ 107 err_display("recv()"); 108 break; 109 } 110 else if(retval == 0) 111 break;
Data transfer socket call (8/10) Data send/recv example – TCP client(cont’d) 113 // print received data 114 buf[retval] = '\0'; 115 printf("[TCP client] %d bytes received...\n", retval); 116 printf("[received data] %s\n", buf); 117 }
Data transfer socket call (9/10) Data send/recv example– TCP server 066 char buf[BUFSIZE+1]; ... 080 while(1){ 081 // data receiving 082 retval = recv(client_sock, buf, BUFSIZE, 0); 083 if(retval == SOCKET_ERROR){ 084 err_display("recv()"); 085 break; 086 } 087 else if(retval == 0) 088 break; 089 090 // print received data 091 buf[retval] = '\0'; 092 printf("[TCP/%s:%d] %s\n", inet_ntoa(clientaddr.sin_addr), 093 ntohs(clientaddr.sin_port), buf);
Data transfer socket call (10/10) Data send/recv example– TCP server(cont’d) 095 // data sending 096 retval = send(client_sock, buf, retval, 0); 097 if(retval == SOCKET_ERROR){ 098 err_display("send()"); 099 break; 100 } 101 }
Application protocol and message design (1/3) Define data format and semantic which is exchanged in application level Application protocol example network
Application protocol and message design (2/3) Message definition ① Message definition ② struct DrawMessage1 { int x1, y1; // line starting point int x2, y2; // line ending point int width; // line width int color; // line color }; struct DrawMessage2 { int x1, y1; // circle center int r; // circle radius int fillcolor; // internal color int width; // line width int color; // line color };
Application protocol and message design (3/3) Message definition ③ struct DrawMessage1 { int type; // = LINE int x1, y1; // line starting point int x2, y2; // line starting point int width; // line width int color; // line color }; struct DrawMessage2 int type; // = CIRCLE int x1, y1; // circle center int r; // circle radius int fillcolor; // internal color int width; // line width int color; // line color
Application protocol and message design (3/3) FileSender.cpp, FileReceiver.cpp