"Linux Programming" socket programming

Source: Internet
Author: User
Tags function prototype socket error stdin htons

Sockets are abstractions of communication endpoints. The file descriptor is created with the open function, and the socket descriptor is created with the socket function. The socket function prototype is as follows:
int socket (int domain, int type, int protocol);//return value: Successfully returned socket descriptor, failed return-1


Domain domains determine the communication characteristics, different fields represent different formats for addresses, and constants that represent the fields begin with AF, representing the address family (addr family):
Type determines the types of sockets and further determines the communication characteristics:

Protocol is typically 0, which indicates that the default protocol is determined by the two parameters above, for example:
    • The communication domain is af_inet and the socket type is SOCK_STREAM, and the default protocol is TCP.
    • The communication domain is af_inet and the socket type is SOCK_DGRAM, and 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 to SHUT_RD, close the read end, unable to read data from the socket, how to SHUT_WR, close the write end, unable to send data through the socket.
Closing the socket descriptor method is the same as closing the file descriptor, all using the close function.
Different CPUs, using different byte sequences to represent data, are divided into big-endian and small-order. For example, a big-endian machine is sent to a small-order machine, and the order of the received data is reversed. In order to avoid this situation, the network transmission is independent of the specific machine type, and the network byte order is adopted. 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 our common X86 structure is the small-end mode. From Wikipedia, the description is very image:

TCP/IP applications provide four common functions for converting between local byte order and network byte order:
    1. HTONL: Local 32-bit integer-to-network byte-order
    2. Htons: Local 16-bit integer-to-network byte-order
    3. Ntohl: Network byte-order to 32-bit integer local byte order
    4. 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 that returns a socket descriptor.
    • Bind: Binds the socket to an IP and port, which is used as the listener object. Note that because the system is assigned to the client's default address, it makes little sense for clients to use the function.
    • Listen: The socket is converted to a listening socket so that the client's connection request can be accepted by the kernel, and the above three steps are the normal steps to set up the listener descriptor .
    • Accept: Hibernate, waiting for the client connection to be accepted by the kernel, three times after the handshake is complete, a new socket descriptor is returned, which connect prompt to the client calling connect, known as the connected descriptor.
    • Send: Send data.
    • RECV: Collect data.
    • Close: Closes the connection, triggering four handshakes.
2. TCP Client:
    • Socket: Creates a socket.
    • Connect: Establishes the connection, indicating the purpose, and the service side of the Accept function corresponds.
    • 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, UDP client: And TCP client basically consistent. If the Connect function is used before sending, the destination address of the sending message is the address specified in the Connect call, so the direct send function is sent. No need to call the Connect function before, send with the SendTo function, this function needs to specify the destination address in the parameter.
Here are some routines.
TCP Client:
/* 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--&GT;CONNECT--&GT;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); /* If Isocketclient does not have a binding address, connect will bind the caller a default address */IRet = connect (isocketclient, const struct SOCKADDR *) &tsocketse    rveraddr, sizeof (struct sockaddr));        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--&GT;BIND--&GT;LISTEN--&GT;ACCEPT--&GT;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 interfaces */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 */IADDR        Len = 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_nt OA (TSoCKETCLIENTADDR.SIN_ADDR), Ntohs (Tsocketclientaddr.sin_port));                /* NET to AscII */* Fork system call Create child process */if (fork () = = 0) {/* child process Source */                    while (1) {/* Recv function receives client data and displays, if Flags is 0, then the same as read, write */ Irecvlen = recv (Inewsocketsever, UCRECVBUF, 999, 0); /* flags generally 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 descriptor is particularly important */}     }} close (Isocketsever); return 0;}


Note that if a sock_stream socket is used, there is no guarantee that the entire data will be accepted at once. The general situation is to read repeatedly in the loop until it returns 0.
UDP client:
/* 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--&GT;CONNECT--&GT;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 descriptor with the server address, * If you do not use the Connect function, 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 server IP\n");      return-1;    } bzero (Tsocketserveraddr.sin_zero, 8); /* There is no need to establish a connection in UDP, but with connect here you can bind the address to isocketclient, and 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 all IP */bzero (Tsocketserveraddr.sin_zero, 8) on this machine;    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;}


UDP client (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 (isock Etclient, Ucsendbuf, strlen (UCSENDBUF), 0, (const struct sockaddr *) &tsocketserveraddr, S            izeof (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 all IP */bzero (Tsocketserveraddr.sin_zero, 8) on this machine;    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;}

Reference: "Advanced Programming for UNIX Environments", chapter 16th.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.