Elementary TCP Sockets Chap 4 Socket functions for TCP client/server Socket Function Socket: create a socket Socket descriptor is a file descriptor in UNIX systems, but is not a file descriptor in Windows Connect Function Connect: establish a connection with a server Kernel chooses both an ephemeral port and the source IP addr Error returns with errno No response to SYN connection timeout (ETIMEDOUT) send one SYN, another 6 sec later, and another 24 sec later If no response after total of 75 sec, the error is returned Response is RST no process on the server port (ECONNREFUSED) ICMP unreachable error message save msg and retry to connect host unreachable (EHOSTUNREACH or ENETUNREACH) The socket is no longer usable and must be closed Bind Function Bind: assign a local protocol address to a socket If port # = 0, the kernel chooses a port (ephemeral port) If wildcard address(INADDR_ANY), the kernel chooses IP addr Example: IPv4 struct sockaddr_in servaddr; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); seraddr.sin_family = AF_INET; seraddr.sin_addr.s_addr = htonl(INADDR_ANY);/* wild card */ seraddr.sin_port = htons(13); /* daytime server */ bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); Example: IPv6 struct sockaddr_in6 servaddr; seraddr.sin6_addr.s_addr =in6addr_any; /* wild card */ Listen Function(1) Listen convert an unconnected socket into passive socket and define connection queue size (backlog) for this listening socket CLOSED LISTEN Listen Function(2) Max number of queued connections is implementation-dependent Accept Function Accept a connection request: return the next completed connection from the connection queue blocked if the completed connection queue is empty If the identity of client is not interested, use NULL pointer instead of cliaddr, addrlen Daytime TCP Server Send and Receive Functions Send: Put n-byte message (stored in buff) into the TCP send buffer int write(int sockfd, const char *buff, int nbytes); int send(int sockfd, const char *buff, int nbytes, int flags); Both return: number of bytes written if OK, -1 on error Blocked if not enough space in TCP send buffer Recv: Get a message(<= bufsize) from the TCP receive buffer and save it into buff int read(int sockfd, char *buff, int bufsize); int recv(int sockfd, char *buff, int bufsize, int flags); Both return: number of bytes read if OK, 0 if received FIN and no more data -1 on error Blocked until TCP receive buffer becomes non-empty n-byte message를 send() 했다고 해서, 수신측에서 recv()할 때 n-byte를 받는 게 아니다. Close Function Close a socket and terminate a TCP connection But, TCP will try to send any data that is already queued in the send buffer, Then normal connection termination sequence take places only if reference count == 0 다른 프로세스가 socket을 share하고 있다면, FIN을 보내지 않는다. To send a FIN explicitly, use shutdown Finding Protocol Addresses from sockets Get the local and foreign protocol address When is getsockname function required ? client가 connect후 자신의 IP addr/port #를 알고자 할 때 0인 port #로 bind한 후 assign된 local port #를 알고자 할 때 socket의 address family를 알고자 할 때 server가 wildcard IP addr를 bind하여 connection이 이루어진 후(accept가 return된 후) local IP addr를 알고자 할 때 When is getpeername function required ? server가 accept후 child process가 fork되고 exec되면 client를 알 수 없음 (예, inetd) Daytime Iterative Server UNIX Process Creation Fork: create a new process Exec: replace current process image with the new executable file Typical Concurrent Servers Server Before accept listenfd After return from accept listenfd connfd After fork return listenfd connfd fork After close sockets Client connection request connection connection connect() connect() connect() listenfd connfd listenfd connfd connect() Summary 12.106.32.254 192.168.42.1 206.168.112.219 203.253.70.44 local ? ? foreign ? ? local 206.168.112.219 1500 foreign 12.106.32.254 21 local ? ? foreign ? ? local 0 21 foreign ? ? Listening socket (=3) local 0 21 foreign ? ? Connected socket (=4) local 12.106.32.254 21 TCP segment FIN foreign 206.168.112.219 1500