服务器端代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#define SERV_PORT 9877
#define MAXLINE 4096
#define LISTENQ 1024
void sig_child(int signo)
{
int status;
while (waitpid(-1,&status,WNOHANG) < 0)
{
printf("waitpid %s\n",strerror(errno));
exit(1);
}
}
void client(int tcpfd,int udpfd)
{
fd_set fs;
FD_ZERO(&fs);
FD_SET(tcpfd,&fs);
FD_SET(udpfd,&fs);
pid_t pid;
int maxfd = tcpfd > udpfd ? tcpfd: udpfd;
int confd;
for (; ;)
{
FD_SET(tcpfd,&fs);
FD_SET(udpfd,&fs);
if (select(maxfd + 1,&fs,NULL,NULL,NULL) < 0)
{
if (errno == EINTR)
continue;
printf("select %s\n",strerror(errno));
exit(1);
}
if (FD_ISSET(tcpfd,&fs))
{
if ((confd = accept(tcpfd,NULL,NULL)) < 0)
{
printf("accept: %s\n",strerror(errno));
exit(1);
}
if ((pid = fork()) < 0)
{
printf("fork: %s\n",strerror(errno));
exit(1);
}
else if (pid == 0)
{
char buf[MAXLINE];
int n;
for (; ;)
{
if ((n = read(confd,buf,MAXLINE)) < 0)
{
printf("read: %s\n",strerror(errno));
exit(1);
}
printf("read over\n");
if (write(confd,buf,n) != n)
{
printf("write: %s\n",strerror(errno));
exit(1);
}
}
exit(0);
}
}
if (FD_ISSET(udpfd,&fs))
{
char buf[MAXLINE];
int n;
struct sockaddr_in clientaddr;
socklen_t socklen = sizeof(clientaddr);
if ((n = recvfrom(udpfd,buf,MAXLINE,0,(struct sockaddr *)&clientaddr,&socklen)) < 0)
{
printf("recvfrom %s\n",strerror(errno));
exit(1);
}
if (sendto(udpfd,buf,n,0,(struct sockaddr*)&clientaddr,socklen) != n)
{
printf("sendto: %s\n",strerror(errno));
exit(1);
}
}
}
}
int main()
{
int udpfd,tcpfd;
if ((udpfd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
{
printf("socket: %s\n",strerror(errno));
exit(1);
}
if ((tcpfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("socket: %s\n",strerror(errno));
exit(1);
}
struct sockaddr_in servaddr;
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(udpfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
printf("udp bind: %s\n",strerror(errno));
exit(1);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(tcpfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
printf("tcp bind: %s\n",strerror(errno));
exit(1);
}
if (listen(tcpfd,LISTENQ) < 0)
{
printf("listen %s\n",strerror(errno));
exit(1);
}
if (signal(SIGCHLD,sig_child) == SIG_ERR)
{
printf("signal: %s\n",strerror(errno));
exit(1);
}
client(tcpfd,udpfd);
}