1, the main process of TCP network programming
Figure 1.1
Note: In Figure 1.1 you can see that close points to read and indicates an end connection. Some people may have doubts, this annotation means that the server is in the process of processing the client is circular read, if the client does not send data server processing client thread is blocked in read here, when the client calls close, service The server processing thread will continue to execute as soon as the read returns-1. If the client does not execute close but simply exits unexpectedly, then the server-side read returns 0 immediately, so it is important to judge the return value after read, depending on the different return values, which are summarized in the trial experiment.
2, structure and related functions
(1) struct sockaddr (common C of Sockets defines a generic address structure)
structsockaddr {
u_charsa_len;//length
U_short sa_family;//Protocol
Char sa_data[14];//data
};
(2) struct sockaddr_in (IP-specific address structure)
structsockaddr_in {
U_char sin_len;//Length
U_short sin_family;//Protocol
U_short sin_port;//Port
STRUCTIN_ADDR SIN_ADDR;//IP Address
Char sin_zero[8];//data
};
(3) struct IN_ADDR
structin_addr {
U_LONGS_ADDR;
};
Used to represent a 32-bit IPv4 address whose byte order is in network order.
(4) int Socket (int domain, int type,int protocol)
Function: Creates a new socket, returns the socket descriptor
Parameter description:
Domain: field type, indicating the protocol stack used, such as TCP/IP using Pf_inet, other Af_inet6, Af_unix
Type: Indicates the type of service you want, such as
Sock_dgram: Datagram Service, UDP protocol
Sock_stream: Streaming services, TCP protocol
Protocol: Generally take 0 (the default protocol is selected by the system according to service type)
(5) int bind (int sockfd,struct sockaddr* my_addr,int addrlen) Feature: Indicates a local endpoint address for a socket
The TCP/IP protocol uses the SOCKADDR_IN structure, which contains the IP address and port number that the server uses to indicate the well-known port number, and then waits for the connection
Parameter description:
SOCKFD: Socket descriptor, indicating the socket that created the connection
MY_ADDR: Local address, IP address and port number
Addrlen: Address length
The port=0 in the socket interface is specified by the kernel port number, set Sin_addr to Inaddr_any, and the IP address is specified by the kernel.
(6) int listen (int sockfd,intinput_queue_size)
Function:
A connection-oriented socket uses it to place a socket in passive mode and prepares to receive incoming connections. For the server, indicating that a socket connection is passive
Parameter description:
SOCKFD: Socket descriptor, indicating the socket that created the connection
Input_queue_size: The queue length used by this socket, specifying the maximum number of requests allowed in the request queue
(7) int accept (int sockfd, structsockaddr *addr, int *addrlen)
Function: Gets the incoming connection request and returns the socket descriptor for the new connection.
A new socket is created for each new connection request, and the server uses the socket only for new connections, and the original listener socket receives additional connection requests. A new socket is used to transfer data on a new connection, and the server closes the socket when it is finished.
Parameter description:
SOCKFD: Socket descriptor, indicating the socket being tapped
Addr: Host address for connection request
Addrlen: Address length
(8) int connect (int sockfd,structsockaddr *server_addr,int Sockaddr_len)
Function: Establish active connection with remote server, return 0 if successful, return 1 if connection fails.
Parameter description:
SOCKFD: Socket descriptor, indicating the socket that created the connection
SERVER_ADDR: Indicates remote endpoint: IP address and port number
Sockaddr_len: Address length
(9) int send (int sockfd, const void * data, int data_len, unsigned int flags)
Function:
Sends data on a TCP connection, returns the length of the successfully transmitted data, and returns 1 when an error occurs. Send copies the outgoing data to the OS kernel, or send a connection-oriented UDP message using send.
Parameter description:
SOCKFD: Socket Descriptor
Data: Pointing to the pointer to send
Data_len: Data length
Flags: usually 0
If the return value of the Send () function is less than Len, you will need to send the remaining data again. 802.3,MTU is 1492B, if the packet is less than 1K, then send () will generally send the light at once.
(a) int recv (int sockfd, void *buf, intbuf_len,unsigned int flags)
Function:
Receives data from TCP, returns the actual length of the data received, and returns 1 when an error occurs.
The server uses it to receive client requests that the customer uses to accept the server's response. If there is no data, it will block. If TCP receives more data than (/less than) the size of the cache, it extracts enough data to fill the cache (/extract all the data and return the number of bytes it actually receives). You can also use recv to receive UDP-oriented packets, if the cache can not load the entire message, fill the cache after the remaining data will be discarded.
Parameter description:
SOCKFD: Socket Descriptor
BUF: Pointer to memory block
Buf_len: Memory block size, in bytes
Flags: typically 0 (Msg_waitall returns when a specified length of data is received), set to Msg_dontwait as Non-blocking
(one) close (int sockfd)
Function:
Undo the socket. If only one process is used, terminate the connection immediately and revoke the socket, if multiple processes share the socket, subtract the reference count by one, and if the reference count drops to 0, close the connection and undo the socket.
Parameter description:
SOCKFD: Socket Descriptor
3. Tcpsocket Client Server Communication Example
The following is a simple example to illustrate the image of the process shown in Figure 1.1, the server waits for the client to connect, after the connection waiting for the client to send data, the server received the data sent to the client and then send back, a "postback" function.
Server code:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> # Include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <
fcntl.h> #include <sys/shm.h> #define MYPORT 8887 #define QUEUE #define BUFFER_SIZE 1024 int main () {
Define SOCKFD int server_sockfd = socket (af_inet,sock_stream, 0);
Define sockaddr_in struct sockaddr_in server_sockaddr;
server_sockaddr.sin_family = af_inet;
Server_sockaddr.sin_port = htons (MyPort);
SERVER_SOCKADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
Bind, successfully returned 0, error returned-1 if (Bind (SERVER_SOCKFD, (struct sockaddr *) &server_sockaddr,sizeof (SERVER_SOCKADDR)) ==-1) {
Perror ("bind");
Exit (1);
printf ("Monitor%d ports \ \ \ MyPort");
Listen, successfully returned 0, error returned-1 if (listen (server_sockfd,queue) = = 1) {perror ("listen");
Exit (1); ///Client Socket CHAr buffer[buffer_size];
struct sockaddr_in client_addr;
socklen_t length = sizeof (CLIENT_ADDR);
printf ("Wait for client to connect \ n");
Successfully returned nonnegative descriptor, error returned-1 int conn = Accept (SERVER_SOCKFD, (struct sockaddr*) &client_addr, &length);
if (conn<0) {perror ("connect");
Exit (1);
printf ("Client is successfully connected \ n");
while (1) {memset (buffer,0,sizeof (buffer));
int len = RECV (conn, buffer, sizeof (buffer), 0);
When the client sends exit or the exception ends, exit if (strcmp (buffer, "exit\n") ==0 | | len<=0) break;
printf ("From client data:%s\n", buffer);
Send (conn, buffer, Len, 0);
printf ("Send to client data:%s\n", buffer);
Close (conn);
Close (SERVER_SOCKFD);
return 0;
}
Client code:
#include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> # Include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <
fcntl.h> #include <sys/shm.h> #define MYPORT 8887 #define BUFFER_SIZE 1024 char* server_ip = "127.0.0.1";
int main () {///defines SOCKFD int sock_cli = socket (af_inet,sock_stream, 0);
Define sockaddr_in struct sockaddr_in servaddr;
memset (&servaddr, 0, sizeof (SERVADDR));
servaddr.sin_family = af_inet; Servaddr.sin_port = htons (MyPort); Server Port servaddr.sin_addr.s_addr = inet_addr (SERVER_IP);
Server IP printf ("Connection%s:%d\n", server_ip,myport);
Connect server, successfully return 0, error return 1 if (sock_cli, (struct sockaddr *) &servaddr, sizeof (SERVADDR)) < 0) {
Perror ("Connect");
Exit (1);
printf ("Server connection succeeded \ n");
Char Sendbuf[buffer_size];
Char Recvbuf[buffer_size]; while (fGets (sendbuf, sizeof (SENDBUF), stdin)!= NULL) {printf ("Send data to Server:%s\n", sendbuf); Send (SOCK_CLI, SendBuf, strlen (SENDBUF), 0);
Send if (strcmp (SendBuf, "exit\n") ==0) break; Recv (SOCK_CLI, Recvbuf, sizeof (RECVBUF), 0);
Receive printf ("Receive data from the server:%s\n", recvbuf);
memset (sendbuf, 0, sizeof (SENDBUF));
memset (recvbuf, 0, sizeof (RECVBUF));
Close (SOCK_CLI);
return 0;
}
Run Result:
TCP Programming Attention:
1, Accept () receive the return value of the client's new socket, the original socket users continue to listen to the port.
2. RECV () returns 0 to represent connection shutdown.