Reference: http://www.cnblogs.com/songQQ/archive/2009/09/03/1559838.html
Http://www.cnblogs.com/newlist/archive/2012/02/19/2358392.html
I. socket Overview
1. socket Definition
Network Programming in Linux is implemented through socket. The socket interface is a special type of I/O, which is also a file descriptor. Each socket is represented by a semi-correlation description {protocol, local address, and local port}; a complete socket is represented by a correlation description {protocol, local address, local port, remote address, remote port. Socket also has a function call similar to opening a file. This function returns an integer socket descriptor, which is then implemented through socket for connection establishment and data transmission.
In counting machines running the TCP/IP protocol, loopback is generally supported by the software virtual IP datagram self-loop interface. If you try to communicate with a computer whose IP address is the same as your own address, data will not be sent to the network, but will be directed to the computer through loopback, a virtual self-loop interface implemented by the kernel. This allows communication between multiple processes on a computer. Currently, many software designs use Sockets for communication between processes in the same computer, which makes the system flexible, you only need to distribute the two processes to different computers without changing the program. Socket is only a method for communication between processes. There are many other methods.
2. socket Type
(1) stream socket (SCOK_STREAM)
Stream sockets provide reliable and connection-oriented communication streams using the TCP protocol.
(2) datagram socket (SCOKET_DGRAM)
For non-connection services, use UDP.
(3) original socket
The original socket allows direct access to underlying protocols such as IP or ICMP for protocol development.
3. indicates the relationship between protocols.
Sa_family; sa_data []; sin_family; unsigned sin_port; in_addr sin_addr; unsigned sin_zero [];};
The two data structures can be converted to each other.
2. Data Storage priority
Data on the internet is transmitted over the network in high byte precedence. Therefore, you sometimes need to convert the byte storage precedence. Here there are four functions. Htons ntohs htonl ntohl implements the conversion of network bytes and hosts respectively. H indicates host, n indicates net, s indicates short is used to convert the port number, and l indicates long is used to convert the IP address.
3. address format conversion
Socket indicates that the IP address is represented in binary format. users prefer to use dot-decimal notation. The two functions can be converted to each other. Inet_ntop and inet_pton are network binary converted to decimal and network binary respectively.
4. Name and address conversion
Gethostbyname and gethostbyaddr convert the host name to an IP address and the IP address to a host name respectively.
Iii. socket BASIC Programming
Bind (sockfd, sockaddr * addr, socklen_t addrlen)
Return Value: 0 -- successful,-1 -- failed
-
Parameter sockfd
-
Specifies the socket to which the address is bound. This is a socket returned by the previous socket function call. After the bind function is called, the socket is associated with a corresponding address. data sent to this address can be read and used through this socket.
-
Parameter addr
-
The specified address. This is an address structure and a valid address structure that has been filled in. After bind is called, the address is associated with the socket specified by the sockfd parameter to achieve the effect described above.
-
Parameter addrlen
-
Like most socket interfaces, the kernel does not care about the address structure. When it copies or transmits the address to the driver, it determines the amount of data to be copied based on this value. This has become one of the most common parameters in the socket interface.
The bind function does not always need to be called. You only need to call this function when your process wants to be associated with a specific address or port. If the user process does not have this need, the program can rely on the Automatic Location Mechanism of the kernel to complete the automatic address selection, without calling the bind function, and avoiding unnecessary complexity. In general, you need to call the bind function for server process problems. For customer processes, you do not need to call the bind function.
Listen:
The listen function changes the connection sleeve interface into a connection sleeve interface, so that a process can accept requests from other processes and thus become a server process. In TCP Server programming, the listen function converts a process into a server and specifies a socket to a passive connection.
The listen function is called after bind-before accept is called. Its function prototype is:
#include<sys/socket.h> listen( sockfd, backlog)
Return Value: 0 -- successful,-1 -- failed
-
Parameter sockfd
-
The socket acting by the listen function is returned by the socket function before sockfd. When the socket fd is returned by the socket function, it is an active socket, that is, the system assumes that the user will call the connect function for this socket and expects it to actively connect with other processes, in Server programming, the user hopes that the socket can accept external connection requests, that is, passively waiting for the user to connect. Because the system considers a socket to be actively connected by default, it is necessary to tell the system in some way that the user process can do this by calling the listen system.
-
Parameter backlog
-
This parameter involves some network details. When a process processes a connection request, other connection requests may exist. Because TCP connection is a process, there may be a semi-connection status. Sometimes, due to too many users trying to connect at the same time, the server process cannot quickly complete the connection request. If this happens, what does the server process want the kernel to do? The kernel maintains a queue in its own process space to track the established connections, but the server process has not taken over the processing or ongoing connections, such a queue kernel cannot be arbitrarily large, so there must be an upper limit of the size. This backlog tells the kernel to use this value as the upper limit.
-
There is no doubt that the server process cannot specify a value at will, and the kernel has a permitted range. This range is implementation-related. It is difficult to have a certain degree of uniformity. Generally, this value is smaller than 30.
After listen is called, the server process can call accept to accept an external request.
Connect: For the client, the bind function is not called and can be replaced by the connect function.
Network Programming socket APIs have a number of core interfaces, and these core interfaces are several seemingly simple functions, although none of them are actually simple. The connect function is a function of these core interfaces. It completes the active connection process.
The function of the connect function is to complete a connection process with a connection protocol. For TCP, It is the three-way handshake process. Its function prototype is as follows:
#include<sys/socket.h> connect( sockfd, sockaddr* server_addr, socklen_t addrlen)
Return Value: 0-success,-1-failure.
To understand the connect function, we need to introduce the function of the connect function. The functions of the connect function can be summarized in one sentence, that is, to complete the connection process of the connection-oriented protocol, which is the main connection. Connection-oriented protocol, when a connection is established, there will always be one party that sends data first, then who calls connect and who sends data first. It is easy to understand the three parameters of connect. I must specify the data sending Address and the data sending address. This is exactly the first two parameters of connect, the third parameter serves the second parameter.
-
Parameter sockfd
-
Specifies the data transmission socket to solve the problem of where to send. The kernel needs to maintain a large number of IO channels, so users must use this parameter to tell the kernel from which IO channel, where data is sent from which socket interface. Sockfd is the value returned by the previous socket.
-
Server_addr
-
Specifies the data transmission destination, that is, the server address. Here, the server is for connect. because connect is called by the active connection party, there must be a connected party, the passive connection party needs to call listen to accept the connect connection request, so that the passive connection party is the server.
-
Parameter addrlen
-
Specify the length of the server_addr struct. We know that there are a lot of address structures in the system, but the socket interface only uses a unified structure to specify the parameter type, so we need to specify a length, so that the kernel has a line when copying parameters.
Like all socket network interfaces, connect will always fail at some time. At this time, it will return-1, and the corresponding errno will be set. You may determine the error through this value. Common Errors include the host inaccessible or timeout error, or the host does not have a process waiting on the corresponding port.
Accept:
For the most important step in Server programming to wait for and accept the client's connection, the accept function completes this step in programming. It extracts the established customer connection from the kernel, and then returns the established connection to the user program. Then, the user program can communicate with its own customers in a point-to-point manner.
The accept function waits for and accepts the customer's request:
#include<sys/socket.h> accept( sockfd, sockaddr* addr, socklen_t* len)
Return: non-negative descriptive word -- success,-1 -- failed
By default, accept will block the process until a customer establishes a connection and returns a new available socket, which is a connection socket. In this case, we need to distinguish two sockets. One socket is just like the accept parameter sockfd. It is a listening socket. After the listen function is called, A socket is transformed from a socket with active connection to a listening socket, while an accept return is a connection socket, which indicates a point-by-point connection that already exists in the network. Naturally, why are there two sockets? The reason is very simple. If a descriptive word is used, it has too many functions, making it unintuitive to use. At the same time, a new descriptive word is generated in the kernel.
-
Parameter sockfd
-
The parameter sockfd is the listening socket mentioned above. This socket is used to listen to a port. When a customer connects to the server, it uses this port number, and this port number is associated with this socket. Of course, the customer does not know the socket details. It only knows one address and one port number.
-
Parameter addr
-
This is a result parameter, which is used to accept a return value. This return value specifies the client address. Of course, this address is described through an address structure. You should know what kind of address structure this address structure is. If you are not interested in the customer's address, you can set this value to NULL.
-
Parameter len
-
As we all think, it is also the result parameter used to accept the size of the above addr structure, which indicates the number of bytes occupied by the addr structure. Similarly, it can be set to NULL.
If accept is returned successfully, the server has established a correct connection with the customer. At this time, the server completes communication with the customer through the socket returned by accept.
Send:
Int send (SOCKET s, const char FAR * buf, int len, int flags );
Both the client and server applications use the send function to send data to the other end of the TCP connection. The client program generally uses the send function to send requests to the server, while the server uses the send function to send responses to the client program.
The first parameter of this function specifies the sender socket descriptor;
The second parameter specifies a buffer for storing the data to be sent by the application;
The third parameter specifies the number of bytes of data to be sent;
The fourth parameter is usually set to 0.
Only the execution process of the send function for Synchronous Socket is described here. When this function is called,
(1) send first compares the length of the data to be sent len and the length of the sending buffer of socket s,
If len is longer than the sending buffer length of s, the function returns SOCKET_ERROR;
(2) If len is smaller than or equal to the length of the sending buffer of s, send first checks whether the protocol is sending data in the sending buffer of s. If yes, wait until the Protocol finishes sending the data, if the Protocol has not started sending data in the sending buffer of s or there is no data in the sending buffer of s, send will compare the remaining space in the sending buffer of s and len
(3) If len is larger than the remaining space, send will wait until the Protocol finishes sending data in the sending buffer of s.
(4) If len is smaller than the remaining space, send only copies the data in the buf to the rest of the space (note that it is not send that transmits the data in the sending buffer of s to the other end of the connection, but the protocol is passed, send only copies the data in the buf to the remaining space in the sending buffer zone of s ).
If the send function successfully copies the data, the actual number of bytes of copy is returned. If an error occurs during sending data copy, the send function returns SOCKET_ERROR; if the network is disconnected when sending data while waiting for the Protocol to send data, the send function also returns SOCKET_ERROR.
Note that the send function successfully copies the data in the buf to the remaining space of the s sending buffer, and then returns the data. However, the data is not necessarily uploaded to the other end of the connection immediately. If a network error occurs during subsequent transmission, the next Socket function will return SOCKET_ERROR. (Each Socket function except send is executing
At the beginning of the line, it is always necessary to wait until the data in the Socket sending buffer is transmitted by the Protocol. If a network error occurs while waiting, the Socket function returns
SOCKET_ERROR)
Note: In Unix systems, if the network is disconnected when sending data while waiting for the send protocol, the process that calls send receives a SIGPIPE signal. The process processes the signal by default and terminates the process.
Tests show that the send function of asynchronous socket can return the corresponding number of bytes when the network is just disconnected, and the select Check is also writable. However, after a few seconds, an error occurs when sending the message again.-1 is returned. Select cannot detect writable data.
Recv:
Int recv (SOCKET s, char FAR * buf, int len, int flags );
Both the client and server applications use the recv function to receive data from the other end of the TCP connection. The first parameter of this function specifies the receiver socket descriptor;
The second parameter specifies a buffer that is used to store the data received by the recv function;
The third parameter specifies the length of the buf;
The fourth parameter is usually set to 0.
Only the execution process of the recv function for Synchronous Socket is described here. When the application calls the recv function,
(1) recv waits for data in the sending buffer of s to be transmitted by the Protocol. If a network error occurs when the Protocol sends data in the sending buffer of s, the recv function returns SOCKET_ERROR,
(2) If there is no data in the sending buffer of s or the data is successfully sent by the protocol, recv first checks the receiving buffer of socket s, if there is no data in the s receiving buffer or the Protocol is receiving data, the recv waits until the Protocol receives the data. When the Protocol receives the data, the recv function copies the data in the s receiving buffer to the buf (note that the data received by the protocol may be larger than the length of the buf, so
In this case, you need to call the recv function several times to copy the data in the s receiving buffer. The recv function only copies data. The protocol is used to receive data ),
The recv function returns the number of bytes of the actual copy. If a recv error occurs during copy, SOCKET_ERROR is returned. If the recv function is interrupted while waiting for the Protocol to receive data, 0 is returned.
Note: In Unix systems, if the network is disconnected when the recv function is waiting for the Protocol to receive data, the process that calls the recv will receive a SIGPIPE signal, the process processes this signal by default.
Programming example:
<stdio.h><stdlib.h><sys/types.h><sys/socket.h><errno.h><.h><unistd.h><netinet/.h> PORT 4321 BUFFER_SIZE 1024 MAX_QUE_CONN_NM 5 ((sockfd = socket(AF_INET,SOCK_STREAM,)) == - server_sockaddr.sin_family ===&(server_sockaddr.sin_zero), i =; setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&i, (bind(sockfd,( sockaddr *)&server_sockaddr,( sockaddr)) == - (listen(sockfd,MAX_QUE_CONN_NM) == - sin_size = ((client_fd = accept(sockfd,( sockaddr *)&client_sockaddr,&sin_size)) == - memset(buf,,((recvbytes = recv(client_fd,buf,BUFFER_SIZE,)) == -<stdio.h><stdlib.h><sys/types.h><sys/socket.h><errno.h><.h><unistd.h><netinet/.h><netdb.h> PORT 4321 BUFFER_SIZE 1024 main( argc, * hostent *(argc < ((host = gethostbyname(argv[])) ==,,argv[ ((sockfd = socket(AF_INET,SOCK_STREAM,)) == - serv_addr.sin_family === *(( in_addr *)host->&(serv_addr.sin_zero), (connect(sockfd,( sockaddr *)&serv_addr,( sockaddr)) == - ((sendbytes = send(sockfd,buf,strlen(buf),)) == -