Linux network programming using multiple processes to implement server concurrent access

Source: Internet
Author: User
Tags bind socket socket error htons

A classic example of concurrent access to a server using a multiple process approach.

Program Implementation function:

1. The client reads a line of text from the standard input and sends it to the server.

2. The server receives the text sent by the client and returns it to the client as is.

3. The client receives the incoming text from the server, outputs it to the standard output, and then continues with the above steps.

Server-side procedures: After a listener socket is established, waits for a client to connect, receives a connection, creates a child process to communicate with the client, and the main process continues to wait for the other client to connect. The code is as follows:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define Serv_port 1113

#define LISTENQ 32

#define Maxline 1024

/*** Connection processing function ***/

void Str_echo (int fd);

Int

Main (int argc, char *argv[]) {

int LISTENFD,CONNFD;

pid_t Childpid;

Socklen_t Clilen;

struct sockaddr_in servaddr;

struct sockaddr_in cliaddr;

if ((LISTENFD = socket (af_inet, sock_stream,0)) ==-1) {

fprintf (stderr, "Socket Error:%sna", Strerror (errno));

Exit (1);

}

/* Server-side FILLED SOCKADDR structure * *

Bzero (&servaddr, sizeof (SERVADDR));

servaddr.sin_family = af_inet;

SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);

Servaddr.sin_port = htons (Serv_port);

/* Bundle LISTENFD Descriptor * *

if (bind (LISTENFD, struct sockaddr*) (&servaddr), sizeof (struct sockaddr)) ==-1) {

fprintf (stderr, "Bind Error:%sna", Strerror (errno));

Exit (1);

}

/* Monitor LISTENFD Descriptor * *

if (Listen (listenfd,5) ==-1) {

fprintf (stderr, "Listen Error:%sna", Strerror (errno));

Exit (1);

}

for (;;) {

Clilen = sizeof (CLIADDR);

/* The server is blocked until the client program establishes the connection * *

if ((Connfd=accept (LISTENFD, (struct sockaddr*) (&cliaddr), &clilen)) ==-1) {

fprintf (stderr, "Accept Error:%sna", Strerror (errno));

Exit (1);

}

After a client has established a connection

if ((Childpid = fork ()) = = 0) {/* Child process/* *

Close (LISTENFD); /* Close the listening socket * *

Str_echo (CONNFD); /* Request to process this client * *

Exit (0);

}

Close (CONNFD);//The parent process closes the connection socket and continues waiting for the arrival of the other connection. * *

}

}

void Str_echo (int sockfd) {

ssize_t N;

Char Buf[maxline];

Again

while ((n = Read (SOCKFD, buf, maxline)) > 0)

Write (SOCKFD, buf, N);

if (N < 0 && errno = = eintr)/is interrupted, reentrant

Goto again;

else if (n < 0) {//Error

fprintf (stderr, "read Error:%sna", Strerror (errno));

Exit (1);

}

}

Client process: Create a connection socket, initiate a connection request to the server, establish the connection, wait for the standard input, after the input completes, sends the input content to the server, then receives the server to send over the content, and will receive the content output to the standard output. The code is as follows:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define Serv_port 1113

#define Maxline 1024

void Str_cli (FILE *fp, int sockfd);

Int

Main (int argc, char **argv)

{

int sockfd;

struct sockaddr_in servaddr;

if (argc!= 2) {

fprintf (stderr, "Usage:tcpcli na");

Exit (0);

}

if ((Sockfd=socket (af_inet,sock_stream,0)) ==-1) {

fprintf (stderr, "Socket Error:%sna", Strerror (errno));

Exit (1);

}

/* Customer program to populate the service side of the information * *

Bzero (&servaddr,sizeof (SERVADDR));

Servaddr.sin_family=af_inet;

Servaddr.sin_port=htons (Serv_port);

if (Inet_pton (Af_inet, argv[1], &servaddr.sin_addr) <= 0) {

fprintf (stderr, "Inet_pton Error:%san", Strerror (errno));

Exit (1);

}

/* Client initiated connection request/*

If Connect (sockfd, (struct sockaddr *) (&SERVADDR), sizeof (struct sockaddr)) ==-1) {

fprintf (stderr, "Connect Error:%san", Strerror (errno));

Exit (1);

}

STR_CLI (stdin, SOCKFD); /* Do it all/*

Exit (0);

}

void

STR_CLI (FILE *fp, int sockfd)

{

int nbytes=0;

Char Sendline[maxline],recvline[maxline];

while (Fgets (Sendline, Maxline, FP)!= NULL) {//read one row from standard input

Write (SOCKFD, Sendline, strlen (sendline));//Send the line to the server

if ((Nbytes=read (SOCKFD, recvline, maxline) = = 0) {//Read data from the server from the SOCKFD

fprintf (stderr, "Str_cli:server terminated Prematurelyn");

Exit (1);

}

Recvline[nbytes]= ';

Fputs (Recvline, stdout);

}

}

Run Result:

1. Start the server-side program first.

viidiot@ubuntu$./dissrv & (running in the background)

2. Start a client

viidiot@ubuntu$./DISCLI 127.0.0.1

hello,world! (Client-entered content)

hello,world! (Content returned by the server side)

3. Input command Netstat-at View TCP connection, you can find that the server side and the client has established a connection, while the server's main process is still listening on the 1113 port, waiting for the arrival of other connections.

viidiot@ubuntu$ Netstat–at

TCP 0 0 *:1113 *:* LISTEN

TCP 0 0 localhost.localdom:1113 localhost.localdo:57430 established

TCP 0 0 localhost.localdo:57430 localhost.localdom:1113 established

The client enters EOF to end the communication.

But when we turn on multiple clients to connect to the server to communicate, and then end the communication by pressing EOF, it's interesting to discover from the background that there are a lot of zombie processes. As shown below:

viidiot@ubuntu$ ps-a

PID TTY Time CMD

19403 PTS/1 00:00:00 Dissrv

19405 PTS/1 00:00:00 Dissrv

19423 PTS/1 00:00:00 Dissrv

19434 PTS/1 00:00:00 Dissrv

19441 PTS/1 00:00:00 Dissrv

The reason for the large number of zombie processes is that when the server child process terminates, a SIGCHLD signal is sent to the parent process. But in our code, the signal is not captured, and the default action of this signal is ignored, so in order to avoid the zombie process, we need to capture sigchld to clear the zombie process.

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.