In the socket network programming, we need to understand some of the necessary knowledge, such as what is the address structure of the SOCKET,IPV4, socket type and so on, or come up directly to see the code will faint, the original Learning Network programming, reading examples, always feel the book is very brief. Or the principle of too many people around the dizzy. I just want you to know simply how to use the socket for network programming and give examples that can be used directly for reference.
1. What is a socket
(1) socket can be regarded as the programming interface of user process and network protocol stack. That is, the application layer can be regarded as the user process, the Transport Layer Network layer Data link layer as a network protocol stack, because these three layers of the transport protocol TCP,IP, etc. are already implemented well, then the socket is connected to the two data transmission. (2) socket can be used not only for inter-process communication of the machine, but also for the process communication of different hosts on the network.
2. IPV4 Socket interface Address structure(1) IPV4 socket address structure is also commonly referred to as the "Internet Sockets address Structure", he named Socket_in, defined in the header file <netinet/in.h> struct sockaddr_in{uint8_t Sin_len;
sa_family_t sin_family;
in_port_t Sin_port;
struct in_addr sin_addr;
Char sin_zero[8];
}; Sin_len: The length of the entire sockaddr_in struct, the first member before the 4.3bsd-reno version is sin_family. Sin_family: Specify this address family, which must be set to Af_inet (here is the protocol used is IPV4) Sin_port: Port Sin_addr:ipv4 address Sin_zero: Generally set it to 0
3. General-purpose address structureBecause sockets are not only used for TCP/IP protocol programming, a common address structure (1) is required to specify the address struct associated with the socket sockaddr{uint8_t Sin_len;sa_family_t sin_family;
Char sa_data[14];
}; Sin_len: Length of the entire SOCKADDR structure sin_family: Specify the Address family sa_data: determined by the sin_family in its form
4. Network byte order(1) byte order1) Big endian byte sequence
the most significant bit is stored at the lowest memory address, and the least significant bit is stored at the highest memory address.
2) Small-endian byte-order The most significant bit is stored at the highest memory address, and the least significant bit is stored at the lowest memory address.
(2) host byte orderdifferent hosts have different byte-order, such as x86 for small-endian, Motorola 6800 is the big end byte order, arm byte order is configurable. (3) network byte ordernetwork byte order defined as big endian byte order
5. Byte-Order conversion functionuint32_t htonl (uint32_t hostlong);uint16_t htons (uint16_t hostshort);uint32_t Ntohl (uint32_t netlong);uint16_t Ntohs (uint16_t netshort);
Description: In the above function, H stands for host,n on behalf of Network,s on behalf of Short,l long.
6. Address conversion function#include <netinet/in.h>#include <arpa/inet.h>
int Inet_aton (const char *CP, struct in_addr *inp);int_addr_t inet_addr (const char *CP);Char *inet_ntoa (struct in_addr in);
7. Socket Type(1) streaming sockets (SOCK_STREAM) provide connection-oriented, reliable data transmission services, no error, no duplication of transmission, and in the order of delivery received. (2) Datagram Sockets (SOCK_DGRAM) provide no-connection services. No error-free guarantees are provided, data may be lost or duplicated, and the order of acceptance is confusing. (3) original socket (SOCK_RAW)
8. Simple Point-to-point shot-back chat program Server side:
#include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> # include<netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <errno.h> #include <string.h> #define ERR_EXIT (m) do {perror (M); Exit (Exit_failure); } while (0) int main () {int listenfd; LISTENFD = socket (pf_inet, sock_stream, 0); if (LISTENFD < 0) err_exit ("socket"); struct sockaddr_in seraddr; memset (&seraddr, 0, sizeof (SERADDR)); seraddr.sin_family = af_inet; Seraddr.sin_port = htons (5788); SERADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any); int bindval = bind (LISTENFD, (struct sockaddr*) &seraddr, sizeof (SERADDR); if (Bindval < 0) Err_exit ("bind"); if ((Listen (LISTENFD, somaxconn)) < 0) Err_exit ("Listen"); struct sockaddr_in peeraddr; socklen_t Peerlen = sizeof (PEERADDR); int conn = accept (LISTENFD, struct sockaddr*) &PEERADDR, &peerlen); IF (Conn < 0) Err_exit ("accept"); Char recvbuf[1024]; while (1) {memset (recvbuf, 0, sizeof (RECVBUF)); int Recvlen = READ (conn, recvbuf, sizeof (RECVBUF)); Fputs (Recvbuf, stdout); Write (conn, recvbuf, Recvlen); } close (LISTENFD); return 0; }
Client side:
#include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> # include<netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <errno.h> #include <string.h> #define ERR_EXIT (m) do {perror (M); Exit (Exit_failure); } while (0) int main () {int sockfd; SOCKFD = socket (pf_inet, sock_stream, 0); if (SOCKFD < 0) err_exit ("socket"); struct sockaddr_in seraddr; memset (&seraddr, 0, sizeof (SERADDR)); seraddr.sin_family = af_inet; Seraddr.sin_port = htons (5788); SERADDR.SIN_ADDR.S_ADDR = inet_addr ("127.0.0.1"); int conn = connect (SOCKFD, (struct sockaddr*) &seraddr, sizeof (SERADDR)); IF (Conn < 0) Err_exit ("Connect"); Char recvbuf[1024]; Char sendbuf[1024]; while (Fgets (sendbuf, sizeof (SENDBUF), stdin)! = NULL) {write (SOCKFD, sendbuf, sizeof (SENDBUF)); Read (SOCKFD, recvbuf, sizeof (recvbuf)); Fputs (Recvbuf, stdout); memset (sendbuf, 0, sizeof (SENDBUF)); memset (recvbuf, 0, sizeof (RECVBUF)); } close (SOCKFD); return 0; }
Here is a problem, when the server is closed, when logged in, the login, will be prompted bind:address already in use, address binding. Since this time the port is occupied and not released, we can use the command: Netstat-an | grep time_wait View Workaround: Call setsockopt as much as possible before bind to set the REUSEADDR socket option. Using the REUSEADDR option allows you to restart the server without having to wait for the time_wait state to disappear.
int on = 1; equals 1 for Open if (setsockopt (LISTENFD, Sol_socket, so_reuseaddr, &on, sizeof (ON)) < 0) err_exit ("setsockopt");
9. Multiple clients (multi-process) Client program does not change server side:
#include <sys/socket.h> #include <sys/types.h> #include <unistd.h> #include <stdlib.h> # include<netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <errno.h> #include <string.h> #define ERR_EXIT (m) do {perror (M); Exit (Exit_failure); } while (0) void Do_service (int conn) {char recvbuf[1024]; while (1) {memset (recvbuf, 0, sizeof (RECVBUF)); int Recvlen = READ (conn, recvbuf, sizeof (RECVBUF)); if (Recvlen = = 0) {printf ("Clent close\n"); Break } if (Recvlen = =-1) {printf ("read Data error\n"); Break } fputs (Recvbuf, stdout); Write (conn, recvbuf, Recvlen); }} int main () {int listenfd; LISTENFD = socket (pf_inet, sock_stream, 0); if (LISTENFD < 0) err_exit ("socket"); struct sockaddr_in seraddr; memset (&seraddr, 0, sizeof (SERADDR)); seraddr.sin_family = Af_inet; Seraddr.sin_port = htons (5788); SERADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any); int on = 1; if (setsockopt (LISTENFD, Sol_socket, so_reuseaddr, &on, sizeof (ON)) < 0) Err_exit ("setsockopt"); int bindval = bind (LISTENFD, (struct sockaddr*) &seraddr, sizeof (SERADDR) if (Bindval < 0) Err_exit ("Bind "); if ((Listen (LISTENFD, somaxconn)) < 0) Err_exit ("Listen"); struct sockaddr_in peeraddr; socklen_t Peerlen = sizeof (PEERADDR); pid_t pid; while (1) {int conn = accept (LISTENFD, (struct sockaddr*) &peeraddr, &peerlen); IF (Conn < 0) Err_exit ("accept"); printf ("address:%s, port:%d\n", Inet_ntoa (PEERADDR.SIN_ADDR), ntohs (pepid = fork (); if (pid = =-1) err_exit ("fork"); if ( PID = = 0) {Close (LISTENFD);d O_service (conn); exit (exit_success); Client Close,so close subprocess//if not closed, it is would continue//recv connect. } else {close (conn); }} close (LISTENFD); return 0; }
Use fork here to open a process, and when there is a connection, fork a process to handle the client connection.
Simple socket network programming under Linux