server程序功能
- 支持多个client与server连接并recv和write
- 每来一个新的client,server都fork一个子进程为client服务(子进程用于与client通信:recv/write)
server程序的实现细节
- 父进程的while(1)循环中,一直调用accept接收新的连接
- 当accept接收成功后,返回新的套接字newconn,然后fork子进程与newconn通信
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAX_CLIENT 10
#define MAX_READ 1024
int main()
{
int serv_fd,con_fd;
struct sockaddr_in serv_addr;
struct sockaddr_in clt_addr;
char addr_dst[INET_ADDRSTRLEN] = {0};
char read_buf[MAX_READ]={0};
int optvar;
pid_t pid;
socklen_t addr_len;
int i = 0;
ssize_t ret ;
serv_fd = socket(AF_INET,SOCK_STREAM,0);
if(-1 == serv_fd)
{
perror("socket");
exit(-1);
}
if(setsockopt(serv_fd, SOL_SOCKET,SO_REUSEADDR,&optvar,sizeof(optvar)) == -1 )
{
perror("setsockopt");
exit(-1);
}
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(8001);
serv_addr.sin_addr.s_addr = htons(INADDR_ANY);
if(bind(serv_fd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) == -1)
{
perror("bind");
exit(-1);
}
if(listen(serv_fd,MAX_CLIENT)== -1)
{
perror("listen");
exit(-1);
}
addr_len = sizeof(clt_addr);
printf("Accepting connections ...\n");
while(1)
{
if((con_fd = accept(serv_fd,(struct sockaddr *)&clt_addr,&addr_len)) == -1)
{
perror("accept");
exit(-1);
}
pid = fork();
if(pid == 0)
{
printf("received from %s at PORT %d\n",inet_ntop(AF_INET,&clt_addr.sin_addr,addr_dst,sizeof(addr_dst)),ntohs(clt_addr.sin_port));
close(serv_fd);
while(1)
{
ret = read(con_fd,read_buf,sizeof(read_buf));
if(ret == 0)
{
printf("client close\n");
close(con_fd);
exit(-1);
}
else if(ret < 0)
{
perror("read");
exit(-1);
}
fputs(read_buf,stdout);
for(i = 0; i < ret ;i++)
{
read_buf[i] = toupper(read_buf[i]);
}
write(con_fd,read_buf,ret);
memset(read_buf,0,sizeof(read_buf));
}
}
else if(pid == -1)
{
perror("fork");
close(serv_fd);
close(con_fd);
exit(-1);
}
else if(pid > 0)
{
close(con_fd);
}
}
return 0;
}