Network programming for embedded linux (3) -- TCPClient Programming 1 overview the client mainly needs to establish connections with the server, request data, and respond to data. from the code point of view, the client program has a lot of code similar to the server program. let's first give a simple client source code, and then
Network programming for embedded linux (3) -- TCP Client program design
1. Overview
The client mainly needs to establish connections with the server, request data, and respond to data. from the code point of view, the client program has a lot of code similar to the server-side Program. let's give a simple client source code and then explain it in detail.
1 /************************************** **************************************** * *******/2/* introduction: TCPClient example. */3 /************************************ **************************************** * ********/4 # include
5 # include
6 # include
7 # include
8 # include
9 # include
10 # include
11 # include
12 13 int main (int argc, char * argv []) 14 {15 int sockfd; 16 char buffer [1024]; 17 struct sockaddr_in server_addr; 18 struct hostent * host; 19 int portnumber, nbytes; 20 21 if (argc! = 3) 22 {23 printf ("Usage: % s hostname portnumber \ a \ n", argv [0]); 24 exit (1 ); 25} 26 27 if (host = gethostbyname (argv [1]) = NULL) 28 {29 herror ("Get host name error \ n "); 30 exit (1); 31} 32 33 if (portnumber = atoi (argv [2]) <0) 34 {35 printf ("Usage: % s hostname portnumber \ a \ n ", argv [0]); 36 exit (1 ); 37} 38 39/* the customer program starts to establish the sockfd descriptor */40 if (sockfd = socket (AF_INET, SOCK_STREAM, 0) =-1) 41 {42 printf ("Socket Error: % s \ a \ n", strerror (errno); 43 exit (1 ); 44} 45/* customer program fill server information */46 bzero (& server_addr, sizeof (server_addr); 47 server_addr.sin_family = AF_INET; 48 server_addr.sin_port = htons (portnumber ); 49 server_addr.sin_addr = * (struct in_addr *) host-> h_addr); 50/* client program initiates connection request */51 if (connect (sockfd, (struct sockaddr *) (& server_addr), \ 52 sizeof (struct sockaddr) =-1) 53 {54 printf ("Connect Error: % s (% d) \ a \ n ", strerror (errno), errno); 55 exit (1); 56} 57/* connection successful */58 if (nbytes = read (sockfd, buffer, 1024 )) =-1) 59 {60 printf ("Read Error: % s \ n", strerror (errno); 61 exit (1 ); 62} 63 buffer [nbytes] = '\ 0'; 64 printf ("I have written Ed: % s \ n", buffer ); 65 66/* end communication */67 close (sockfd); 68 exit (0); 69}
The client program connects to the server before data exchange. Before that, the server IP address and port number must be known. 2. Name Address Conversion
In general, people do not want to remember lengthy IP addresses during use. especially in IPv6, the address length is as high as 128 bits, so it is even more impossible to remember such a long IP address. therefore, using host names is a good choice. in Linux, there are also some functions that can convert host names and addresses. The most common functions are gethostbyname, gethostbyaddr, and getaddrinfo, both of them can be converted between IPv4 and IPv6 addresses and host names. specifically, gethostbyname converts the host name to an IP address, while gethostbyaddr converts the IP address to a host name. In addition, getaddrinfo can automatically identify IPv4 and IPv6 addresses.
Struct hostent {char * h_name;/* official host name */char ** h_aliases;/* host alias */int h_addrtype;/* address type */int h_length; /* Address length */char ** h_addr_list;/* address pointer array pointing to IPv4 or IPv6 */}
After this function is called, information about the hostent struct can be returned. the getaddrinfo function involves an addrinfo struct, as shown below:
Struct addrinfo {int ai_flags;/* AI_PASSIVE, AI_CANONNAME; */int ai_family;/* Address Family */int ai_socktype;/* socket type */int ai_protocol; /* protocol type */size_t ai_addrlen;/* Address length */char * ai_canoname;/* host name */struct sockaddr * ai_addr;/* socket struct */struct addrinfo * ai_next; /* next pointer linked list */}
For the hostent struct, the addrinfo struct contains more information.
If the error code is not stored in the global variable errno, the error code is stored in h_errno. use the herrno function to access the variable h_errno. the use of this function is the same as that of perror, if 29 rows in the example.
In addition, you can use the gethostname function to obtain the name of the local host. The Returned name can be gethostbyname. the declaration of this function is as follows:
#include
int gethostname(char *hostname, size_t size);
Hostname: a buffer pointer pointing to the host name to be stored;
The syntax of the getaddrinfo function is as follows:
Before calling hints, you must first set hints service clues. it is an addrinfo struct that lists the common option values of this struct.
3. connect to the server
After the client creates a socket and fills in the server information structure, it can connect to the server. for example, the syntax of the 51st-line connect function in the example is as follows:
When the connect function fails, the global variable errno contains the following values:
The EACCES and EPERM users attempt to connect to the broadcast address if the socket broadcast flag is not set or the connection fails due to the firewall policy.
After the connect function returns a successful result, you can use sockfd as the socket descriptor to connect to the server. some previously mentioned I/O functions can be used to communicate with the server.
4. test results
Compile the two programs as simple_server and simple_client respectively, establish two connections with the linux operating system through SecureCRT, and run the two programs respectively.
Note: localhost is a local cyclic address, which represents the IP address of the local machine, expressed in dotted decimal format as 127.0.0.1. this is a special IP address, which is usually used to test whether the IP protocol is normal. this address is frequently used for local network program debugging.