This chapter explains the basic socket functions required to write a complete TCP client/server program.
Socket function
#include <sys/socket.h>int socket (int family,int type,int protocol); // return: Success is a non-negative descriptor, or 1 if an error occurs
The family parameter indicates the protocol family, which is one of the following constant values
The type parameter indicates the socket type, which is one of the following constant values
The protocol parameter is a constant value of one of the following protocol types, or set to 0 to select the system default values for the given family and type combinations
Socket functions showing basic TCP client/server programs
Connect function
TCP client uses the Connect function to establish a connection to the TCP server
#include <sys/socket.h>int connect (int sockfd,conststruct sockaddr * servaddr,socklen_t addrlen) // return: 0 If successful, 1 if error
SOCKFD is the socket descriptor returned by the socket function, and the second, third parameter is a pointer to the socket address structure and the size of the structure.
Bind function
The BIND function assigns a local protocol address to a socket
#include <sys/socket.h>int bind (int sockfd,conststruct sockaddr * Myaddr,socklen_t addrlen); // returns: 0 if successful, or 1 if there is an error
Listen function
The Listen function is only called by the TCP server, and it does two things.
1. When the socket function creates a socket, it is assumed to be an active socket (the client socket that will call connect to initiate the connection)
The Listen function converts an unbound socket into a passive socket, indicating that the kernel should accept connection requests for that socket.
2. The second parameter of this function specifies the maximum number of connections that the kernel should queue for the corresponding socket.
#include <sys/socket.h>int Listen (int sockfd,int backlog); // returns: 0 if successful, or 1 if there is an error
This function should usually be called after the socket and bind functions are called, and before the Accept function is called.
Accept function
The Accept function is called by the TCP server to return the next completed connection from the completed Connection queue team header. If the completed connection queue is empty, then the process is put to sleep.
#include <sys/socket.h>int accept (int sockfd,struct sockaddr *cliaddr,socklen_t * addrlen); // return: A non-negative descriptor if successful, or 1 if an error occurs
The parameters cliaddr and Addrlen are used to return the protocol address of the connected peer process (customer).
If the accept succeeds, then its return value is a completely new descriptor generated automatically by the kernel, representing the TCP connection to the returned client.
When we discuss the Accept function, we call its first parameter a listening socket (created by the socket and then used as the descriptor for the first parameter of bind and listen), which says its return value is a connected socket descriptor.
The following program demonstrates the use of all of the above functions, which is an iterative server. is a time to display the client IP address and port number to get the server program.
1#include"Unp.h"2#include <time.h>3 4 int5MainintargcChar**argv)6 {7 intlistenfd, CONNFD;8 socklen_t Len;9 structsockaddr_in servaddr, cliaddr;Ten CharBuff[maxline]; One time_t ticks; A -LISTENFD = Socket (Af_inet, Sock_stream,0); - theBzero (&SERVADDR,sizeof(SERVADDR)); -servaddr.sin_family =af_inet; -SERVADDR.SIN_ADDR.S_ADDR =htonl (inaddr_any); -Servaddr.sin_port = htons ( -);/*Daytime Server*/ + -Bind (LISTENFD, (SA *) &servaddr,sizeof(SERVADDR)); + A Listen (LISTENFD, Listenq); at - for ( ; ; ) { -Len =sizeof(CLIADDR); -CONNFD = Accept (LISTENFD, (SA *) &cliaddr, &len); -printf"connection from%s, Port%d\n", -Inet_ntop (af_inet, &cliaddr.sin_addr, Buff,sizeof(Buff)), in Ntohs (Cliaddr.sin_port)); - toTicks =Time (NULL); +snprintf (Buff,sizeof(Buff),"%.24s\r\n", CTime (&ticks)); - Write (CONNFD, Buff, strlen (buff)); the * Close (CONNFD); $ }Panax Notoginseng}
View Code
Fork and EXEC functions
The fork function is the only way to derive a new process from UNIX
#include <unistd.h>pid_t fork (void); // returns: 0 in child process, child process ID in parent process, 1 if error
The only way that executable program files stored on a hard disk can be executed by UNIX is if one of the 6 exec functions is already called
#include <unistd.h>intEXECL (Const Char*path,Const Char*arg, ...);intEXECLP (Const Char*file,Const Char*arg, ...);intExecle (Const Char*path,Const Char*arg,...,Char*Constenvp[]);intExecvConst Char*path,Char*Constargv[]);intEXECVP (Const Char*file,Char*Constargv[]);intEXECVPE (Const Char*file,Char*ConstArgv[],Char*Constenvp[]);intFexecve (intFdChar*ConstArgv[],Char*ConstEnvp[]);
Exec replaces the current process image with a new program file, and the new program is usually executed from the main function.
About the fork and EXEC functions you can view previously written apue articles: http://www.cnblogs.com/runnyu/p/4638913.html
Concurrent Server
There is an example of an iterative server, which is enough for a simple server like time acquisition.
Then when the service of a customer request may take a long time, we do not want the entire server to be occupied by a single customer for a long period, but want to serve multiple customers at the same time.
The simplest way for UNIX to write concurrent server programs is to fork a sub-process to serve each customer, and here is a typical outline of a concurrent server program.
1 pid_t pid;2 intLISTENFD,CONNFD;3Listenfd=Socket (...);4 /*fill in sockaddr_in{} with server ' Swell-known port*/5 Bind (listenfd,...);6 Listen (LISTENFD,LISTENQ);7 for(;;)8 {9Connfd=accept (LISTENFD,...);/*probably blocks*/ Ten if((Pid=fork ()) = =0) One { AClose (LISTENFD);/*Child closes listening socket*/ -Doit (CONNFD);/*Process the request*/ -Close (CONNFD);/*Done with the This client*/ theExit0);/*Child terminates*/ - } -Close (CONNFD)/*Parent closes connected socket*/ -}
View Code
When a connection is established, accept returns, the server then calls Fork, and then the child process serves the client (via the connected socket CONNFD), and the parent process waits for another connection (via the listener socket LISTENFD)
Close function
The usual Unix close function can also be used to close a socket.
#include <unistd.h>int close (int sockfd); // returns: 0 if successful, or 1 if there is an error
Descriptor reference count
In the concurrency server framework above, the parent process closes a connected socket only causing the corresponding descriptor to have the app count value minus 1.
Since the reference count value is greater than 0, this close call does not raise the TCP four packet connection termination sequence, knowing that the child process terminates the TCP connection by using close to close the socket (the number of references is 0).
GetSockName and Getpeername functions
GetSockName returns the local protocol address associated with a socket, and the Getpeername function returns the address of the foreign protocol associated with a socket.
#include <sys/socket.h>int getsockname (int sockfd,struct sockaddr *localaddr, socklen_t *addrlen); int getpeername (int sockfd,struct sockaddr *peeraddr,socklen_t *addrlen); // all returns: 0 if successful, or 1 if there is an error
UNP Study notes (fourth. Basic TCP Socket Programming)