Linux socket programming instance based on C/C ++

Source: Internet
Author: User
Tags socket error

Socket programming instance

CodeThe server in the instance sends the string "Hello, you are connected!" to the client through a socket connection! ". If you run the software on the server and the client runs the software on the client, the client receives the string.

The software code of the server is as follows:

# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <sys/types. h>
# Include <netinet/in. h>
# Include <sys/socket. h>
# Include <sys/Wait. H>
# Define servport 3333/* server listening port number */
# Define backlog 10/* Maximum number of simultaneous connection requests */

Main ()
{
Int sock_fd, client_fd;/* sock_fd: Listener socket; client_fd: Data Transmission socket */
Int sin_size;
Struct sockaddr_in my_addr;/* local address information */
Struct sockaddr_in remote_addr;/* client address information */
If (sock_fd = socket (af_inet, sock_stream, 0) =-1 ){
Perror ("socket creation error! ");
Exit (1 );
}
My_addr.sin_family = af_inet;
My_addr.sin_port = htons (servport );
My_addr.sin_addr.s_addr = inaddr_any;
Bzero (& (my_addr.sin_zero), 8 );
If (BIND (sock_fd, (struct sockaddr *) & my_addr, sizeof (struct sockaddr) =-1 ){
Perror ("BIND error! ");
Exit (1 );
}
If (Listen (sock_fd, backlog) =-1 ){
Perror ("Listen error! ");
Exit (1 );
}
While (1 ){
Sin_size = sizeof (struct sockaddr_in );
If (client_fd = accept (sock_fd, (struct sockaddr *) & remote_addr, & sin_size) =-1 ){
Perror ("Accept error ");
Continue;
}
Printf ("received a connection from % s \ n", inet_ntoa (remote_addr.sin_addr ));
If (! Fork () {/* child process code segment */
If (send (client_fd, "Hello, you are connected! \ N ", 26, 0) =-1 ){
Perror ("send error! ");
}
Close (client_fd );
Exit (0 );
}
Close (client_fd );
}
}

The server workflow is as follows:

First, call the socket function to create a socket, then call the BIND function to bind it to the local address and a local port number, and then call listen to listen on the corresponding socket, when accpet receives a connection service request, a new socket is generated. The server displays the IP address of the client and sends the string "Hello, you are connected!" to the client through the new socket! ". Close the socket.

The fork () function in the Code instance generates a sub-process to process the data transmission part. The value returned by the fork () Statement for the sub-process is 0. Therefore, the IF statement containing the fork function is the sub-process code part, and it is executed concurrently with the parent Process Code part after the if statement.

ClientProgramThe Code is as follows:

# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <netdb. h>
# Include <sys/types. h>
# Include <netinet/in. h>
# Include <sys/socket. h>
# Define servport 3333
# Define maxdatasize 100/* maximum data transmission volume each time */

Main (INT argc, char * argv [])
{
Int sock_fd, recvbytes;
Char Buf [maxdatasize];
Struct hostent * Host;
Struct sockaddr_in serv_addr;
If (argc <2 ){
Fprintf (stderr, "Please enter the server's hostname! \ N ");
Exit (1 );
}
If (host = gethostbyname (argv [1]) = NULL ){
Herror ("gethostbyname error! ");
Exit (1 );
}
If (sock_fd = socket (af_inet, sock_stream, 0) =-1 ){
Perror ("socket creation error! ");
Exit (1 );
}
Serv_addr.sin_family = af_inet;
Serv_addr.sin_port = htons (servport );
Serv_addr.sin_addr = * (struct in_addr *) Host-> h_addr );
Bzero (& (serv_addr.sin_zero), 8 );
If (connect (sock_fd, (struct sockaddr *) & serv_addr, sizeof (struct sockaddr) =-1 ){
Perror ("Connect error! ");
Exit (1 );
}
If (recvbytes = Recv (sock_fd, Buf, maxdatasize, 0) =-1 ){
Perror ("Recv error! ");
Exit (1 );
}
Buf [recvbytes] = '\ 0 ';
Printf ("Received: % s", Buf );
Close (sock_fd );
}

The client first obtains the Server IP address through the server domain name, creates a socket, calls the connect function to establish a connection with the server, receives data sent from the server after the connection is successful, and closes the socket.

The gethostbyname () function completes domain name conversion. Because IP addresses are hard to remember and read/write, domain names are often used to represent hosts for convenience, which requires domain name and IP address conversion. Function prototype:

Struct hostent * gethostbyname (const char * Name );

The structure type returned by the function as hosten. Its definition is as follows:

Struct hostent {
Char * h_name;/* Host's official domain name */
Char ** h_aliases;/* an array of host aliases ending with null */
Int h_addrtype;/* return address type, in the Internet environment is AF-INET */
Int h_length;/* the length of the address in bytes */
Char ** h_addr_list;/* an array ending with 0, containing all addresses of the Host */
};
# Define h_addr h_addr_list [0]/* The first address in H-ADDR-list */

When gethostname () is called successfully, a pointer to struct hostent is returned. If the call fails,-1 is returned. When gethostbyname is called, you cannot use the perror () function to output error information. Instead, use the herror () function to output error information.

The principle of a connectionless client/server program is the same as that of a connected Client/Server. The difference between the two is that customers in a connectionless Client/Server generally do not need to establish a connection, when sending and receiving data, you must specify the address of the remote machine.

Blocking and non-blocking

The blocking function does not allow the program to call another function until it completes the specified task. For example, when a program executes a function call to read data, the next program statement is not executed until the function completes the read operation. When the server runs the accept statement without a customer connection request, the server stops waiting for the connection request on the accept statement. This is called blocking ). The non-blocking operation can be completed immediately. For example, if you want the server to check whether a client is waiting for a connection, you can accept the connection. Otherwise, you can continue to do other things by setting the socket to a non-blocking method. The non-blocking Socket enables the Accept call to return immediately when no client is waiting.

# Include <unistd. h>
# Include <fcntl. h>
......
Sockfd = socket (af_inet, sock_stream, 0 );
Fcntl (sockfd, f_setfl, o_nonblock );
......

By setting the socket as a non-blocking method, you can implement "polling" Several sockets. When an attempt is made to read data from a non-blocking socket without data waiting for processing, the function will return immediately, the returned value is-1, and the errno value is ewouldblock. However, this "Round Robin" will make the CPU in a busy waiting mode, thus reducing performance and wasting system resources. The call to select () can effectively solve this problem. It allows you to hook the process itself and enable the system kernel to listen to any activity of a set of file descriptors required by the system kernel, as long as the activity is confirmed on any monitored file descriptor, the Select () call will return information indicating that the file descriptor is prepared, so as to select random changes for the process, the CPU overhead does not need to be wasted because the process itself tests the input. The prototype of the select function is:

Int select (INT numfds, fd_set * readfds, fd_set * writefds, fd_set * limit TFDs, struct timeval * timeout );

Readfds, writefds, and limit TFDs are the collection of read, write, and exception handling file descriptors monitored by select. If you want to determine whether data can be read from the standard input and a socket descriptor, you only need to add the file descriptor 0 and the corresponding sockdtfd of the standard input to the readfds set; the numfds value is the file descriptor with the highest number to be checked plus 1. In this example, the numfds value should be sockfd + 1. When the SELECT statement is returned, readfds will be modified, indicates that a file descriptor has been read. You can test it through fd_issset. To set, reset, and test the file descriptor corresponding to fd_set, it provides a set of macros:

Fd_zero (fd_set * Set) ---- clears a file descriptor set;
Fd_set (int fd, fd_set * Set) ---- Add a file descriptor to the file descriptor set;
Fd_clr (int fd, fd_set * Set) ---- clears a file descriptor from the file descriptor set;
Fd_isset (int fd, fd_set * Set) ---- try to determine whether the file descriptor is set.

The timeout parameter is a pointer to the struct timeval type, which enables select () to return if no file descriptor is ready after waiting for a long time. Struct timeval data structure:

Struct timeval {
Int TV _sec;/* seconds */
Int TV _usec;/* microseconds */
};

POP3 client instance

The following code instance is based on the POP3 client protocol and connects to the mail server and retrieves emails from a specified user account. Commands that interact with the email server are stored in the string array popmessage. The program sends these commands in sequence through a do-while loop.

# Include <stdio. h>
# Include <stdlib. h>
# Include <errno. h>
# Include <string. h>
# Include <netdb. h>
# Include <sys/types. h>
# Include <netinet/in. h>
# Include <sys/socket. h>
# Define pop3servport 110
# Define maxdatasalize 4096

Main (INT argc, char * argv []) {
Int sock_fd;
Struct hostent * Host;
Struct sockaddr_in serv_addr;
Char * popmessage [] = {
"User userid \ r \ n ",
"Pass password \ r \ n ",
"Stat \ r \ n ",
"List \ r \ n ",
"Retr 1 \ r \ n ",
"DELE 1 \ r \ n ",
"Quit \ r \ n ",
Null
};
Int ilength;
Int imsg = 0;
Int iend = 0;
Char Buf [maxdatasize];

If (host = gethostbyname ("Your. Server") = NULL ){
Perror ("gethostbyname error ");
Exit (1 );
}
If (sock_fd = socket (af_inet, sock_stream, 0) =-1 ){
Perror ("socket error ");
Exit (1 );
}
Serv_addr.sin_family = af_inet;
Serv_addr.sin_port = htons (pop3servport );
Serv_addr.sin_addr = * (struct in_addr *) Host-> h_addr );
Bzero (& (serv_addr.sin_zero), 8 );
If (connect (sock_fd, (struct sockaddr *) & serv_addr, sizeof (struct sockaddr) =-1 ){
Perror ("Connect error ");
Exit (1 );
}

Do {
Send (sock_fd, popmessage [imsg], strlen (popmessage [imsg]), 0 );
Printf ("have sent: % s", popmessage [imsg]);

Ilength = Recv (sock_fd, BUF + iend, sizeof (BUF)-iend, 0 );
Iend + = ilength;
Buf [iend] = '\ 0 ';
Printf ("Received: % s, % d \ n", Buf, imsg );

Imsg ++;
} While (popmessage [imsg]);

Close (sockfd );
}

ArticleSource: http://www.diybl.com/course/3_program/c++/cppsl/200861/118803_3.html

Related Article

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.