Server program:
#include <sys/wait.h> #include <string.h> #include <string.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include ;signal.h> #include <arpa/inet.h> #include <sys/select.h> #include <sys/time.h> #include <
unistd.h> #define Serv_port 3334 #define LISTENQ 5 #define Maxline 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) goto again;
else if (n < 0) perror ("read");
} void sig_chld (int signo) {pid_t pid;
int stat;
while (PID = Waitpid ( -1, &stat, Wnohang)) > 0) printf ("Child%d terminated\n", PID);
Return
}int main (int argc, char **argv) {int listenfd, CONNFD, UDPFD, Nready, MAXFDP1;
Char Mesg[maxline];
pid_t Childpid;
Fd_set RSet;
ssize_t N;
Socklen_t Len;
const int on = 1;
struct sockaddr_in cliaddr, servaddr;
void sig_chld (int);
* * 4create listening TCP socket/LISTENFD = socket (af_inet, sock_stream, 0);
Bzero (&servaddr, sizeof (SERVADDR));
servaddr.sin_family = af_inet;
SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
Servaddr.sin_port = htons (Serv_port);
SetSockOpt (LISTENFD, Sol_socket, so_reuseaddr, &on, sizeof (on));
Bind (LISTENFD, (struct sockaddr *) &servaddr, sizeof (SERVADDR));
Listen (LISTENFD, Listenq);
/* 4create UDP socket */UDPFD = socket (af_inet, SOCK_DGRAM, 0); Bzero (&servadDr, sizeof (SERVADDR));
servaddr.sin_family = af_inet;
SERVADDR.SIN_ADDR.S_ADDR = htonl (Inaddr_any);
Servaddr.sin_port = htons (Serv_port);
Bind (UDPFD, (struct sockaddr *) &servaddr, sizeof (SERVADDR)); Signal (SIGCHLD, SIG_CHLD);
/* Must call WAITPID () */Fd_zero (&rset);
MAXFDP1 = ((LISTENFD>UDPFD)? listenfd:udpfd) + 1; for (;;)
{Fd_set (LISTENFD, &rset);
Fd_set (UDPFD, &rset);
if (Nready = select (MAXFDP1, &rset, NULL, NULL, NULL) < 0) {if (errno = = eintr) Continue
/* Back to for () */Else Perror ("select");
} if (Fd_isset (LISTENFD, &rset)) {len = sizeof (CLIADDR);
CONNFD = Accept (LISTENFD, (struct sockaddr *) &cliaddr, &len); if ((Childpid = fork ()) = = 0) {/* Child process */CLose (LISTENFD); /* Close Listening socket * * STR_ECHO (CONNFD);
/* Process the request * * exit (0); Close (CONNFD); /* Parent closes connected socket/} if (Fd_isset (UDPFD, &rset)) {len = size
of (CLIADDR);
n = recvfrom (UDPFD, MESG, Maxline, 0, (struct sockaddr*) &cliaddr, &len);
SendTo (UDPFD, MESG, N, 0, (struct sockaddr *) &cliaddr, Len); }
}
}
57-67 Create a well-known port that listens on TCP sockets and bundles the servers, setting the SO_REUSEADDR socket option to prevent existing connections on the port.
70-77 also creates a UDP socket and bundles the same port as the TCP socket. There is no need to set the SO_REUSEADDR socket option before calling bind because the TCP port is independent of the UDP port.
78 Establish a signal handler for SIGCHLD because the TCP connection will be processed by a child process.
83-90 We call select just to wait for the readable condition of the TCP socket or the readable condition of the UDP socket. Since our SIG_CHLD signal processing function may interrupt our call to select, we need to handle the EINTR error.
Author: csdn Blog Ctthuangcheng
See more highlights of this column: http://www.bianceng.cnhttp://www.bianceng.cn/OS/unix/