Sockets are abstractions of communication endpoints. The file description descriptor is created with the open function, and the socket descriptive descriptor is created with the socket function. The socket function prototype is as follows:
int socket (int domain, int type, int protocol);//return value: Successful return socket descriptive descriptor, failed return-1
Domain domains determine communication characteristics. Different fields represent different formats for addresses, and constants that represent fields begin with AF. Represents the address family (addr family):
watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvbmvzdgxlcg==/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma==/ Dissolve/70/gravity/southeast ">
Type determines the socket types. Further identifying communication features:
Protocol is typically 0, which indicates that the default protocol is determined by the two parameters described above. Like what:
- The communication domain is af_inet. The socket type is sock_stream. The default protocol is TCP.
- The communication domain is af_inet. The socket type is SOCK_DGRAM. The default protocol is UDP.
To close one end of a socket, you can use the Shutdown function:
int shutdown (int sockfd, int how);//return value: Successful return 0, failure return-1
How is SHUT_RD, closing the read end, unable to read the data from the socket; how is SHUT_WR. Closes the write end and cannot send data through the socket.
Close the method of describing the descriptor and closing the file description of the descriptor the same is true with the close function.
Different CPUs. Use different byte sequences to represent data, big-endian and small-order. such as big-endian machines sent to small-endian machines, the received data order is reversed. In order to avoid this situation, the network transmission is independent of the detailed machine type, and the network byte order is used. The sender converts the native sequence to the network byte order and the receiver converts the received network byte order to the native sequence.
TCP/IP uses big-endian byte order, which is the network byte order, and the X86 structure we often use is the small-end mode. From Wikipedia, the descriptive narrative is very graphic:
TCP/IP applications provide four common functions for converting between local byte order and network byte order:
- HTONL: Local 32-bit integer-to-network byte-order
- Htons: Local 16-bit integer-to-network byte-order
- Ntohl: Network byte-order to 32-bit integer local byte order
- Ntohs: Network byte-order to 16-bit integer local byte order
The following are the calling procedures for the related function interfaces of TCP and UDP programs. 1. TCP Server:
- Socket: establishes a transport endpoint. Returns a socket descriptive descriptor.
- Bind: Binds the socket to an IP and port. This IP and port are used as listener objects. Note that because the system is assigned to the client's default address. So it doesn't make much sense for the client to use this function.
- Listen: The socket is converted to a listening socket so that the client connection request can be accepted by the kernel, and the above three steps are the normal steps for setting up a listener descriptive descriptor .
- Accept: Hibernate. Wait for the client connection to be accepted by the kernel. Three times after the handshake is complete, a new socket descriptive descriptor is returned. The descriptive narrative connect prompt to the client calling connect. is known as a connected descriptive descriptor.
- Send: Send data.
- RECV: Collect data.
- Close: Closes the connection, triggering four handshakes.
2, TCPclient:
- Socket: Creates a socket.
- Connect: Establish a connection. Specify the purpose, corresponding to the Accept function on the service side.
- Send: Send data.
- RECV: Collect data.
3. UDP Service side:
- Socket: establishes a socket.
- Bind: Binds the listening IP and port.
- Recvfrom: Blocking waits for data to arrive.
4, UdpClient: and TcpClient basically consistent. Assume that you used the Connect function before sending. The destination address for sending the message is the address specified in the Connect call. So the direct send function is sent.
No use before calling the Connect function, send with sendto function. This function needs to specify the destination address in the parameters.
Here are some routines.
TCPclient:
/* Socket programming client code based on TCP protocol */#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>/* client : * SOCKET-->CONNECT-->SEND/RECV */#define SERVER_PORT 8888int Main (int argc, char **argv) {int iRet; int isocketclient; struct sockaddr_in tsocketserveraddr; int Isendlen; unsigned char ucsendbuf[1000]; if (argc! = 2) {printf ("usage:\n"); printf ("%s <server_ip>\n", argv[0]); return-1; }/* 1. Build Socket */isocketclient = socket (af_inet, sock_stream, 0); /* 2. Establish a TCP connection to the server */tsocketserveraddr.sin_family = af_inet; /* recommend */Tsocketserveraddr.sin_port = htons (Server_port); /* Host to net short */if (Inet_aton (argv[1], &tsocketserveraddr.sin_addr) = = 0)/* string to server IP */{print F ("Invalid server IP\n"); return-1; } bzero (Tsocketserveraddr.sin_zeRO, 8); /* Assume that isocketclient does not have a binding address. Connect will bind a default address to the caller */IRet = connect (isocketclient, (const struct sockaddr *) &tsocketserveraddr, sizeof (struct s OCKADDR)); if (IRet = =-1) {/* Connection failed */printf ("Connect error\n"); return-1; } while (1) {if (Fgets (UCSENDBUF, 999, stdin)) {/* send function Send data */Isendlen = SE nd (isocketclient, Ucsendbuf, strlen (UCSENDBUF), 0); if (Isendlen = =-1) {/* function error */close (isocketclient); return-1; }}} return 0;}
TCP Service side:
/* Socket Programming server-side code based on TCP protocol */#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h>/* Server: * SOCKET-->BIND-->LISTEN-->ACCEPT-->SEND/RECV */#define SERVER_PORT 8888# Define BACKLOG 10int Main (int argc, char **argv) {int iRet; int Iaddrlen; int isocketsever; int inewsocketsever; struct sockaddr_in tsocketserveraddr; struct sockaddr_in tsocketclientaddr; int Irecvlen; unsigned char ucrecvbuf[1000]; /* After the child process dies, the SIGCHLD signal is sent to the parent process, * this is set to ignore SIGCHLD signal */signal (sigchld,sig_ign); /* 1. Build socket * Af_inet:ipv4 Internet Protocols * SOCK_STREAM:TCP protocol * 0: usually assignment */isocketsever = socket (af_ INET, Sock_stream, 0); if (Isocketsever = =-1) {printf ("Socket error\n"); return-1; }/* 2. Configure the socket * settings to listen to which IP on this machine, port */TSOCKETSERVERADDR.Sin_family = af_inet; /* recommend */Tsocketserveraddr.sin_port = htons (Server_port); /* Host to net short */tSocketServerAddr.sin_addr.s_addr = htonl (Inaddr_any); /* bind to native all network interface */bzero (Tsocketserveraddr.sin_zero, 8); IRet = Bind (Isocketsever, (const struct sockaddr *) &tsocketserveraddr, sizeof (struct sockaddr)); if (IRet = =-1) {printf ("bind error\n"); return-1; }/* 3. Open Socket Listening mode * Establish service Request queue, backlog is maximum number of connections */IRet = Listen (isocketsever, backlog); if (IRet = =-1) {printf ("Listen error\n"); return-1; } while (1) {/* 4. Hibernate, waiting to establish a connection * The client address is stored in the second parameter * later read and write with the new socket descriptor */ Iaddrlen = sizeof (struct sockaddr); Inewsocketsever = Accept (Isocketsever, (struct sockaddr *) &tsocketclientaddr, &iaddrlen); if (inewsocketsever! =-1) {/* Successfully established connection */printf ("Get Connect from ip:%s, port:%d\n", inEt_ntoa (TSOCKETCLIENTADDR.SIN_ADDR), Ntohs (Tsocketclientaddr.sin_port)); /* NET to AscII */* Fork system call Create child process */if (fork () = = 0) {/* Child process Source code */ while (1) {/* Recv function receives client data and displays, assuming that flags is 0, then the same as read, write */ Irecvlen = recv (Inewsocketsever, UCRECVBUF, 999, 0); /* Flags normally set to 0 */if (Irecvlen <= 0) {/* recv error (-1) or connection off Closed (0) */close (inewsocketsever); printf ("disconnected!\n"); return-1; } else {Ucrecvbuf[irecvlen] = ' + '; printf ("The recv msg is:%s\n", ucrecvbuf); }}} else {/* Parent Process Code */Close (Inewsocketsev ER); /* Parent Process Close connected descriptive narrator is especially important */}}} close (Isocketsever); return 0;}
Note that the SOCK_STREAM socket is assumed to be used. There is no guarantee that the entire data can be accepted at once.
The normal situation is to repeat the reading in the loop. Until 0 is returned.
UdpClient:
/* Socket programming client code based on the UDP protocol */#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>/* client : * SOCKET-->CONNECT-->SEND/RECV */#define SERVER_PORT 8888int Main (int argc, char **argv) {int iRet; int isocketclient; struct sockaddr_in tsocketserveraddr; int Isendlen; unsigned char ucsendbuf[1000]; if (argc! = 2) {printf ("usage:\n"); printf ("%s <server_ip>\n", argv[0]); return-1; }/* 1. Build Socket */isocketclient = socket (af_inet, SOCK_DGRAM, 0); /* 2. Does not establish a real connection, just let the socket descriptive descriptor with the server address, * Assuming that the Connect function is not used, you should use the Sento function to send the data */tsocketserveraddr.sin_family = af_inet; /* recommend */Tsocketserveraddr.sin_port = htons (Server_port); /* Host to net short */if (Inet_aton (argv[1], &tsocketserveraddr.sin_addr) = = 0)/* string to server IP */{print F ("Invalid serverIP\n "); return-1; } bzero (Tsocketserveraddr.sin_zero, 8); /* There is no need to establish a connection in UDP, but using connect here is able to bind the address to isocketclient, the Send function does not need address information */IRet = connect (const struct SOC KADDR *) &tsocketserveraddr, sizeof (struct sockaddr)); if (IRet = =-1) {printf ("Connect error\n"); return-1; } while (1) {if (Fgets (UCSENDBUF, 999, stdin)) {/* send function Send data */Isendlen = SE nd (isocketclient, Ucsendbuf, strlen (UCSENDBUF), 0); if (Isendlen = =-1) {/* function error */close (isocketclient); return-1; }}} return 0;}
UDP Service side:
/* Socket Programming server-side code based on the UDP protocol */#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h>/* Server: * socket-->bind-->sendto/recvfrom */#define SERVER_PORT 8888int Main (int argc, char * * argv) {int iRet; int Iaddrlen; int isocketsever; struct sockaddr_in tsocketserveraddr; struct sockaddr_in tsocketclientaddr; int Irecvlen; unsigned char ucrecvbuf[1000]; /* 1. Build socket * Af_inet:ipv4 Internet Protocols * SOCK_DGRAM:UDP protocol * 0: usually assignment */isocketsever = socket (af_i NET, SOCK_DGRAM, 0); if (Isocketsever = =-1) {printf ("Socket error\n"); return-1; }/* 2. Configure the socket * settings to monitor which IP of this machine, port */tsocketserveraddr.sin_family = af_inet; /* recommend */Tsocketserveraddr.sin_port = htons (Server_port); /* Host to net short */TsocketserveradDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any); /* Fill in the native IP */bzero (Tsocketserveraddr.sin_zero, 8); IRet = Bind (Isocketsever, (const struct sockaddr *) &tsocketserveraddr, sizeof (struct sockaddr)); if (IRet = =-1) {printf ("bind error\n"); return-1; while (1) {/* Receives the client data, the address information is placed in the tsocketclientaddr struct */iaddrlen = sizeof (struct sockaddr); Irecvlen = Recvfrom (Isocketsever, UCRECVBUF, 999, 0, (struct sockaddr *) &tsocketclientaddr, &iaddrlen); if (Irecvlen > 0) {Ucrecvbuf[irecvlen] = ' + '; printf ("Get msg from%s:%s\n", Inet_ntoa (TSOCKETCLIENTADDR.SIN_ADDR), ucrecvbuf); }} close (Isocketsever); return 0;}
UdpClient (no connect function):
/* Socket programming client code based on the UDP protocol */#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>/* client : * Socket-->sendto/recvfrom */#define SERVER_PORT 8888int Main (int argc, char **argv) {int iRet; int isocketclient; struct sockaddr_in tsocketserveraddr; int Isendlen; unsigned char ucsendbuf[1000]; if (argc! = 2) {printf ("usage:\n"); printf ("%s <server_ip>\n", argv[0]); return-1; }/* 1. Build Socket */isocketclient = socket (af_inet, SOCK_DGRAM, 0); /* 2. Set server address */tsocketserveraddr.sin_family = htonl (af_inet); /* recommend */Tsocketserveraddr.sin_port = htons (Server_port); /* Host to net short */if (Inet_aton (argv[1], &tsocketserveraddr.sin_addr) = = 0)/* string to server IP */{print F ("Invalid server IP\n"); return-1; } bzero (Tsocketserveraddr.sin_zero, 8); WHile (1) {if (Fgets (UCSENDBUF, 999, stdin)) {/* SendTo function Send data */Isendlen = SendTo (Isocketclient, Ucsendbuf, strlen (UCSENDBUF), 0, (const struct SOCKADDR *) &tsocketservera DDR, sizeof (struct sockaddr)); if (Isendlen = =-1) {/* function error */close (isocketclient); return-1; }}} return 0;}
UDP Service side (no connect function):
/* Socket Programming server-side code based on the UDP protocol */#include <stdio.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <signal.h>/* Server: * socket-->bind-->sendto/recvfrom */#define SERVER_PORT 8888int Main (int argc, char * * argv) {int iRet; int Iaddrlen; int isocketsever; struct sockaddr_in tsocketserveraddr; struct sockaddr_in tsocketclientaddr; int Irecvlen; unsigned char ucrecvbuf[1000]; /* 1. Build socket * Af_inet:ipv4 Internet Protocols * SOCK_DGRAM:UDP protocol * 0: usually assignment */isocketsever = socket (af_i NET, SOCK_DGRAM, 0); if (Isocketsever = =-1) {printf ("Socket error\n"); return-1; }/* 2. Configure the socket * settings to monitor which IP of this machine, port */tsocketserveraddr.sin_family = af_inet; /* recommend */Tsocketserveraddr.sin_port = htons (Server_port); /* Host to net short */TsocketserveradDR.SIN_ADDR.S_ADDR = Inaddr_any; /* Fill in the native IP */bzero (Tsocketserveraddr.sin_zero, 8); IRet = Bind (Isocketsever, (const struct sockaddr *) &tsocketserveraddr, sizeof (struct sockaddr)); if (IRet = =-1) {printf ("bind error\n"); return-1; } while (1) {/* receives client data. Address information is placed in the TSOCKETCLIENTADDR structure */iaddrlen = sizeof (struct sockaddr); Irecvlen = Recvfrom (Isocketsever, UCRECVBUF, 999, 0, (struct sockaddr *) &tsocketclientaddr, &iaddrlen); if (Irecvlen > 0) {Ucrecvbuf[irecvlen] = ' + '; printf ("Get msg from%s:%s\n", Inet_ntoa (TSOCKETCLIENTADDR.SIN_ADDR), ucrecvbuf); }} close (Isocketsever); return 0;}
Section 16th, advanced Programming for the UNIX environment.
"Linux Programming" socket programming