Socket programming-a simple example

Source: Internet
Author: User
Tags connect socket htons

The basic steps for socket programming are as follows:

Server Client

 

++

Create socket create socket

++

|

|

|

++

Address assignment (

Your own address) server address)

++

|

|

|

++ |

Bind |

Socket and address |

++ |

|

|

|

++ |

Listen |

++ |

| ++

| <------------------------------ Connect Server

| ++

++ |

Accept |

++ |

|

| ++

| Recv and send

| Data Processing

| ++

++ |

Obtained with accept |

|

Recv and send |

++ |

|

|

|

++

Close socket close socket

++

 

According to the above steps, the server code is

# Include <stdio. h> <br/> # include <string. h> <br/> # include <sys/socket. h> <br/> # include <netinet/in. h> <br/> # include <stdlib. h> <br/> # include <syslog. h> <br/> # include <errno. h> <br/> # define max_listen_num 5 <br/> # define send_buf_size 100 <br/> # define recv_buf_size 100 <br/> # define listen_port 1010 <br/> int main () <br/>{< br/> int listen_sock = 0; <br/> int app_sock = 0; <br/> struct sockaddr_in host ADDR; <br/> struct sockaddr_in clientaddr; <br/> int socklen = sizeof (clientaddr); <br/> char sendbuf [send_buf_size] = {0 }; <br/> char recvbuf [recv_buf_size] = {0}; <br/> int sendlen = 0; <br/> int recvlen = 0; <br/> int retlen = 0; <br/> int leftlen = 0; <br/> char * PTR = NULL; <br/> memset (void *) & hostaddr, 0, sizeof (hostaddr); <br/> memset (void *) & clientaddr, 0, sizeof (clientaddr); <br/> Ho Staddr. sin_family = af_inet; <br/> hostaddr. sin_port = htons (listen_port); <br/> hostaddr. sin_addr.s_addr = htonl (inaddr_any); <br/> listen_sock = socket (af_inet, sock_stream, 0); <br/> If (listen_sock <0) <br/>{< br/> syslog (log_err, "% s: % d, create socket failed", _ file __, _ line __); <br/> exit (1); <br/>}< br/> If (BIND (listen_sock, (struct sockaddr *) & hostaddr, sizeof (hostaddr) <0) <br/> {<B R/> syslog (log_err, "% s: % d, bind socket failed", _ file __, _ line _); <br/> exit (1 ); <br/>}< br/> If (Listen (listen_sock, max_listen_num) <0) <br/>{< br/> syslog (log_err, "% s: % d, listen failed ", _ file __, _ line _); <br/> exit (1); <br/>}< br/> while (1) <br/>{ <br/> app_sock = accept (listen_sock, (struct sockaddr *) & clientaddr, & socklen); <br/> If (app_sock <0) <br/>{< br/> syslog (log_err, "% S: % d, accept failed ", _ file __, _ line _); <br/> exit (1 ); <br/>}< br/> sprintf (sendbuf, "Welcome % s: % d here! /N ", inet_ntoa (clientaddr. sin_addr.s_addr), clientaddr. sin_port); <br/> // send data <br/> sendlen = strlen (sendbuf) + 1; <br/> retlen = 0; <br/> leftlen = sendlen; <br/> PTR = sendbuf; <br/> // while (leftlen) <br/> {<br/> retlen = Send (app_sock, PTR, sendlen, 0 ); <br/> If (retlen <0) <br/>{< br/> If (errno = eintr) <br/> retlen = 0; <br/> else <br/> exit (1); <br/>}< br/> leftlen-= retlen; <br/> PTR + = retlen; <br/>}< br/> // receive data <br/> recvlen = 0; <br/> retlen = 0; <br/> PTR = recvbuf; <br/> leftlen = recv_buf_size-1; <br/> // DO <br/> {<br/> retlen = Recv (app_sock, PTR, leftlen, 0 ); <br/> If (retlen <0) <br/>{< br/> If (errno = eintr) <br/> retlen = 0; <br/> else <br/> exit (1); <br/>}< br/> recvlen + = retlen; <br/> leftlen-= retlen; <br/> PTR + = retlen; <br/>}< br/> // while (recvlen & leftlen); <br/> printf ("receive data is: % s ", recvbuf); <br/> close (app_sock); <br/>}< br/> close (listen_sock); </P> <p> return 0; </P> <p >}< br/>

 

 

The client code is:

# Include <stdio. h> <br/> # include <string. h> <br/> # include <sys/socket. h> <br/> # include <netinet/in. h> <br/> # include <syslog. h> <br/> # include <errno. h> <br/> # include <stdlib. h> <br/> # define max_listen_num 5 <br/> # define send_buf_size 100 <br/> # define recv_buf_size 100 <br/> # define server_port 1010 <br/> int main () <br/>{< br/> int sock_fd = 0; <br/> char recvbuf [recv_buf_size] = {0 }; <br/> char sendbuf [send_buf_size] = {0}; <br/> int recvlen = 0; <br/> int retlen = 0; <br/> int sendlen = 0; <br/> int leftlen = 0; <br/> char * PTR = NULL; <br/> struct sockaddr_in ser_addr; </P> <p> memset (& ser_addr, 0, sizeof (ser_addr); <br/> ser_addr.sin_family = af_inet; <br/> inet_aton ("127.0.0.1 ", (struct in_addr *) & ser_addr.sin_addr); <br/> ser_addr.sin_port = htons (server_port); <br/> sock_fd = socket (af_inet, sock_stream, 0 ); <br/> If (sock_fd <0) <br/> {<br/> syslog (log_err, "% s: % d, create socket failed", _ file __, _ line _); <br/> exit (1); <br/>}< br/> If (connect (sock_fd, (struct sockaddr *) & ser_addr, sizeof (ser_addr) <0) <br/>{< br/> syslog (log_err, "% s: % d, connect socket failed", _ file __, _ line _); <br/> exit (1); <br/>}< br/> // receive data <br/> recvlen = 0; <br/> retlen = 0; <br/> PTR = recvbuf; <br/> leftlen = recv_buf_size-1; <br/> // DO <br/> {<br/> retlen = Recv (sock_fd, PTR, leftlen, 0); <br/> If (retlen <0) <br/>{< br/> If (errno = eintr) <br/> retlen = 0; <br/> else <br/> exit (1 ); <br/>}< br/> recvlen + = retlen; <br/> leftlen-= retlen; <br/> PTR + = retlen; <br/>}< br/> // while (recvlen & leftlen); <br/> printf ("receive data is: % s", recvbuf ); <br/> sprintf (sendbuf, "Hello server/N"); <br/> // send data <br/> sendlen = strlen (sendbuf) + 1; <br/> retlen = 0; <br/> leftlen = sendlen; <br/> PTR = sendbuf; <br/> // while (leftlen) <br/>{< br/> retlen = Send (sock_fd, PTR, sendlen, 0); <br/> If (retlen <0) <br/>{< br/> If (errno = eintr) <br/> retlen = 0; <br/> else <br/> exit (1 ); <br/>}< br/> leftlen-= retlen; <br/> PTR + = retlen; <br/>}< br/> close (sock_fd ); </P> <p >}< br/>

 

 

Now a simple TCP socket communication example has been completed. Here are several problems to be explained.

1) header file:

Sys/socket. h contains socket-related functions, such as socket, send and Recv, and struct sockaddr.

Netinet/in. h contains the address structure, such as struct sockaddr_in.

Errno. h contains errno and eintr

Syslog. h contains syslog-related information. The printed result is in/var/log/messages.

 

2) socket address

For IPv4, the address is struct sockaddr_in. The specific structure is as follows:

Struct in_addr {in_addr_t s_addr;/* 32-bit IPv4 address * // * network byte ordered */}; struct sockaddr_in {uint8_t sin_len;/* length of structure (16) */sa_family_t sin_family;/* af_inet */in_port_t sin_port;/* 16-bit TCP or UDP port number */* network byte ordered */struct in_addr sin_addr; /* 32-bit IPv4 address * // * network byte ordered */Char sin_zero [8];/* unused */};


Sin_len is usually not concerned or filled in (used only when the routing socket is used and used by the kernel to process the address structure of various Protocol clusters ).
BIND, connect, sendto, and sendmsg will pass the socket address from the program to the kernel; while accept, recvfrom, recvmsg, getpeername, and getsockname will pass the address from the kernel to the program. Because the address structure of different protocol clusters is different, a common pointer must be provided to transmit the address. For ansi c, void * is generally used, but the socket is generated earlier than ansi c, therefore, this mechanism is not used, but a general address structure struct sockaddr is used for processing.
Struct sockaddr {uint8_t sa_len; sa_family_t sa_family;/* address family: af_xxx value */Char sa_data [14];/* protocol-specific address */};

The IPv6 socket address is struct sockaddr_in6.

Struct in6_addr {uint8_t s6_addr [16];/* 128-bit IPv6 address * // * network byte ordered */}; # define sin6_len/* required for compile-time tests */struct sockaddr_in6 {uint8_t sin6_len;/* length of this struct (28) */sa_family_t sin6_family; /* af_inet6 */in_port_t sin6_port;/* Transport Layer port # * // * network byte ordered */uint32_t handle;/* flow information, undefined */struct in6_addr sin6_addr; /* IPv6 address * // * network byte ordered */uint32_t sin6_scope_id;/* Set of interfaces for a scope */};

For the sockaddr-in6, We can't store it with the generic address struct sockaddr, but instead use the new generic address structure struct sockaddr_storage, which is large enough to store the addresses supported by any system.
Struct sockaddr_storage {uint8_t ss_len;/* length of this struct (implementation dependent) */sa_family_t ss_family;/* address family: af_xxx value */* Implementation-dependent elements to provide: * A) alignment sufficient to fulfill the alignment requirements of * All socket address types that the system support * B) enough storage to hold any type of socket address that the * system supports. */};
Several common address Structures

3) Length of the related function
For a function (such as Connect) that transmits an address from a program to the kernel, its length is an integer value, telling the kernel the length of the address to copy.
The length of a function (such as accpt) passed to a program from the kernel is an integer pointer and a value-result parameter. There are two purposes: 1. Tell the kernel address structure length so that the kernel does not exceed this length during copy; 2. Return the actual copy length of the kernel.

4) byte order
Socket-related functions use network byte

5) Address Conversion Function
Inet_aton, inet_ntoa, and inet_addr convert the IPv4 string address to a 32-bit network byte address.
Inet_ptonand inet_ntop can be used to convert IPv4 and IPv6 addresses.

6) backlog in listen
You need to know the meaning of this value first. For a listen socket, there are two queues: one is the incomplete connection queue (only receives SYN ); one is the complete connection queue (three-way handshake is completed ). The accept function is used to obtain a socket in the complete connection queue. Backlog refers to the number of queues, but it cannot be defined explicitly in all places. It does not indicate which queue actually represents or the sum of the two queues. Generally
At the same time, the number of connections processed is 1.5 times that of backlog, which is used in many places.

7) getsockname and getpeername
The two functions can be associated with the socket address. getsockname and getpeername can respectively obtain the address of the user and the peer address.
int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen)int getpeername(int sockfd , struct sockaddr * peeraddr , socklen_t * addrlen ); 



















 

 

 

 

 

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.