My Windows Socket API experience Author: Don Gang
This article is some of the experiences that I have summed up in the practice of MS-Windows, HP-UNIX network programming, only for your reference. The Socket Functions talked herein if there is no special instructions, all refer to the Windows Socket API.
1. WSASTARTUP function int WSAStartup (Word WVersionRequested, LPWSADATA LPWSADATA); using the socket program must call the WSAStartup function before using the socket. The first parameter of this function indicates the Socket version used by the program request, where the high-level byte refers to the sub-version, the low byte indicating the master version; the operating system uses the second parameter to return the requested Socket version information. When an application calls the WSAStartup function, the operating system searches for the corresponding Socket library based on the requested socket library, then binds the found Socket library to the application. The application can call other Socket functions in the requested Socket library. This function returns 0 after the function is successful. Example: If a program is to use a version 2.1 version of Socket, the program code is wvrsionRequested = MakeWord (2, 1); err = WSAStartup (WVersionRequested, & WSADATA);
Second, WSACLEANUP Functions INT WSACLEANUP (VOID); After the application is completed, the WSACLEanup function is called to unbind the WSACleanup function to unbind the Socket library and release the system resources occupied by the Socket library.
Third, the Socket function socket socket (int AF, INT TYPE, INT Protocol); application calls the socket function to create a socket that can communicate network communication. The first parameter specifies the protocol family of the communication protocol used by the application, for the TCP / IP protocol, the parameter sets the PF_INET; the second parameter specifies the type of socket to create, the junction type type is SOCK_STREAM, Data News The socket type is SOCK_DGRAM; the third parameter specifies the communication protocol used by the application. This function returns the descriptor of the newly created socket if the call is successful. The socket descriptor is a value of an integer type. There is a socket descriptor table in the process space of each process, which stores a corresponding relationship between socket descriptors and socket data structures. This table has a field stores a descriptor of the newly created socket, and the other field stores the address of the socket data structure, so it can find its corresponding socket data structure according to the socket descriptor. Each process has a socket descriptor table in its own process space, but the socket data structure is in the kernel buffer of the operating system. Below is an example of creating a stream jacket: struct protoent * ppe; ppe = getProtobyname ("tcp"); socket listensocket = socket (PF_INET, SOCK_STREAM, PPE-> P_PROTO);
Fourth, the CloseSocket Function Int CloseSocket (Socket S); the CloseSocket function is used to close a descriptor as a S socket. Since there is a socket descriptor table in each process, each socket descriptor in the table corresponds to a socket data structure located in the operating system buffer, so there may be several sets. The word descriptor points to the same socket data structure. The socket data structure has a specifically a field that stores the reference number of the structure, that is, how many socket descriptors come to the structure. When the CLOSESOCKET function is called, the operating system checks the value of this field in the socket data structure. If it is 1, it indicates that only one socket descriptor points to it, so the operating system will first describe S in the socket. The correspondence in the table is cleared, and the S-touch data structure is released; if the field is greater than 1, the operating system only clears the corresponding terms in the socket descriptor table, and puts S The reference number of the corresponding socket data structure is reduced. CloseSocket function returns 0 if the execution is successful, otherwise returns socket_error.
V. Send Functions Int Serad (INT LEN, INT FLAR * BUF, INT LEN, INT FLAGS); whether the customer or server application uses the Send function to send data to the other end of the TCP connection. The client generally uses the Send function to send a request to the server, and the server usually uses the Send function to send a response to the client program. The first parameter of this function specifies the transmitting end socket descriptor; the second parameter indicates a buffer that stores the application to send data; the third parameter indicates the number of bytes of the data to be sent; fourth The parameters are generally 0. Here only describes the execution flow of the SEEND function of the synchronous socket. When this function is called, the Send first compares the length of the length of the data to be transmitted, and the length of the transmission buffer of the socket S, if the length of the transmission buffer of the s, the function returns socket_ERROR; if Len is less than or equal to S Send the length of the buffer, then first check if the protocol is transmitting data in the transmission buffer in S, if it is to send the data, if the data is transmitted, if the protocol has not started to send the S of the data or the transmission buffer of S. There is no data in the middle, then Send compares the remaining space and LEN of the send buffer of S, if LEN is greater than the remaining space size Send, waiting for the protocol to send the data in the transmission buffer, if the LEN is less than the remaining space size Send is only Putting the data in the buf to the remaining space (note that the send is transmitted to the data in the transmission buffer in the SEnd to the other end of the connection, but the protocol is transmitted, the Send is only transmitted to the data of the data in the BUF. The remaining space of the buffer). If the send function COPY data is successful, returns the number of bytes of the actual copy, if the send occurs when Copy data, then Send returns to Socket_ERROR; if the network is disconnected when sending data is waiting for the protocol, then the send function returns Socket_ERROR . Note that the send function returns the remaining space of the data in the BUF successfully COPY to S, but this data does not necessarily be immediately transmitted to the other end of the connection. If a network error occurs during the subsequent transfer, the next Socket function returns SOCKET_ERROR. (Each Socket Function except Socket function is performed at the beginning of the execution, the data in the send buffer of the socket is first successfully transferred, if a network error occurs while waiting, then the Socket function returns socket_ERROR) Note: Under UNIX systems, if the network is disconnected when sending data when the data is waived, the process calling the Send will receive a SIGPIPE signal, and the process of the process is terminated by the process.
6. Recv function int RECV (Socket S, CHAR FAR * BUF, INT LEN, INT FLAGS); whether it is customer or server applications receive data from the other end of the TCP connection. The first parameter of this function specifies the receiving end socket descriptor; the second parameter indicates a buffer, which is used to store the data received by the RECV function; the third parameter indicates the length of the BUF; fourth The parameters are generally 0. Here, only the execution flow of the RECV function of the synchronous socket is described here. When the application calls the RECV function, the data in the transmit buffer of the RECV is first passed by the protocol. If the protocol occurs when the data is transmitted in the transmission buffer in the transmission buffer, then the RECV function returns to socket_error, if S is transmit buffer After no data or data is successfully sent by the protocol, the Recv first checks the receiving buffer of the socket S, if there is no data or protocol in the S-receive buffer, then the RECV is waiting, only the protocol receives data to the protocol complete. When the protocol has completed the data, the RECV function puts the data COPY to BUF in the reception buffer of S (Note that the data received by the protocol may be greater than the length of the BUF, so in this case to call several Recv functions to put s The data COPY in the reception buffer is complete .Recv function is only a COPY data, and the real receiving data is the protocol to complete), the RECV function returns its actual COPY byte number. If the RECV is wrong when COPY, then it returns to socket_error; if the RECV function is interrupted when the RECV function receives data when the protocol is received, then it returns 0. Note: Under the UNIX system, if the network is disconnected when the RECV function receives data at the waiting protocol, then the process that calls the RECV will receive a SIGPIPE signal, the process of the process is terminated by the process is terminated.
7. Bind function int bind (socket s, int namelen); After a socket is created, there is a default IP address and the default port number in the socket data structure. A service program must call the BIND function to bind it to it an IP address and a specific port number. The client generally does not have to call the BIND function to bind the IP address and the break number for its socket. The first parameter of this function specifies the Socket descriptor to be bound; the second parameter specifies a SockAddr structure, which is defined: struct sockaddr {u_short sa_family; char sa_data [14];}; sa_family specified address family For the TCP / IP protocol, it gives it AF_INET. When binding the TCP / IP protocol's socket, we usually use another address structure: strunt sockaddr_in {short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero [8];}; sin_family set AF_INET; SIN_PORT indicates the port number; there is only one unique field S_addr in the SIN_ADDR structure, indicating the IP address, which is an integer. Generally, the function inet_addr () converts the IP address in the form of the string into the unsigned long-type integer value after reset Give S_ADDR. Some servers are multi-hook hosts, at least two network cards, then running HTONL (INADDR_ANY) to s_addr when the service program running on such a server is binding IP addresses for its socket, so the benefits are no matter which The client program on the network segment can communicate with the service program; if only a fixed IP address is bound to the SOCKET of the service program running on the multi-hockey, then only the IP address is in the same network segment. The client can communicate with the service program. We use 0 to populate the SIN_ZERO array, the purpose is to make the size of the SOCKADDR_IN structure consistent with the SockAddr structure. The following is an example of a bind function call: struct sockaddr_in saddr; saddr.sin_family = AF_INET; saddr.sin_port = htons (8888); saddr.sin_addr.s_addr = htonl (INADDR_ANY); bind (ListenSocket, (struct sockaddr *) & saddr, SIZEOF (SADDR)); Eight, Listen Functions Int Listen (Socket S, Int Backlog); Server can call the listen function to make its flow sleeve S in listening status. Flow sockets S will maintain a client connection request queue, which is up to the backlog client connection request. If the function is successful, return 0; if the execution fails, return socket_ERROR.
9. Accept function socket accept (socket s, structure sockaddr far * addr, int far * addrlen); Server call ACCEPT function takes out a customer in the client connection request queue from the client connection request queue in the listening state Request, and create a new socket to create a connection channel with the customer socket. If the connection is successful, return the descriptor of the newly created socket, and then switch the data with the customer socket. The new creation is Tag; if it fails, it returns invalid_socket. The first parameter of this function specifies a flow sleeve in the listening state; the operating system utilizes the second parameter to return the address structure of the newly created socket; the operating system uses the third parameter to return to the newly created socket The length of the address structure of the word. Here is an example accept call: struct sockaddr_in ServerSocketAddr; int addrlen; addrlen = sizeof (ServerSocketAddr); ServerSocket = accept (ListenSocket, (struct sockaddr *) & ServerSocketAddr, & addrlen); ten, connect function int connect (SOCKET s, const struct SockAddr Far * name, int namelen; customer program calls the client Socket S to connect to the service socket on the specific port of the computer specified by Name. If the connection is successful, Connect returns 0; if it fails, returns Socket_ERROR. Here is an example: struct sockaddr_in daddr; memset ((void *) & daddr, 0, sizeof (daddr)); daddr.sin_family = AF_INET; daddr.sin_port = htons (8888); daddr.sin_addr.s_addr = inet_addr ( "133.197 .22.4 "); Connect (Client SockAddr *) & Daddr, Sizeof (Daddr));