解决问题:
1.并发等待子进程终止(避免出现僵死进程)
2.防止accept,read,write等阻塞函数的中断不能重启
未解决问题
1.服务器非正常终止,崩溃,重启
客户端代码:
vi c2.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#define OWNPORT 9877
#define MAXLINE 4096
int main(int argc,char **argv)
{
if (argc != 2)
{
printf("please add <ipadress>\n");
exit(1);
}
int sockfd;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("socket %s\n",strerror(errno));
exit(1);
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(OWNPORT);
if (inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0)
{
printf("inet_pton %s\n",strerror(errno));
exit(1);
}
if (connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
printf("connect %s\n",strerror(errno));
exit(1);
}
char buf[MAXLINE + 1];
while (fgets(buf,MAXLINE,stdin) != NULL)
{
/*int pos = strlen(buf);
buf[pos] = '\n';
buf[pos + 1] = '\0';*/
int n = 0;
int size = strlen(buf);
while ((n = write(sockfd,buf + n,size)) > 0 || errno == EINTR)
{
size -= n;
if (size <= 0)
break;
}
if (n < 0)
{
printf("wriet %s\n",strerror(errno));
exit(1);
}
size = 0;
if((n = read(sockfd,buf,MAXLINE)) > 0 || errno == EINTR);
if (n < 0)
{
printf("read %s\n",strerror(errno));
exit(1);
}
buf[n] = '\0';
fputs(buf,stdout);
}
return 0;
}
服务器端:
vi s2.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/wait.h>
#define OWNPORT 9877
#define LISTENQ 1024
#define MAXLINE 4096
#define MAXSIZE 4096
void sig_child(int signo)
{
int pid;
int stat;
while ((pid = waitpid(-1,&stat,WNOHANG)) < 0)
{
printf("waitpid %s\n",strerror(errno));
exit(1);
}
}
void writeback(int fd)
{
int n;
char buf[MAXSIZE];
int size = 0;
errno = 0;
while ((n = read(fd,buf,MAXSIZE)) > 0)
{
size += n;
if (n < 0)
{
printf("read %s\n",strerror(errno));
exit(1);
}
n = 0;
while ((n = write(fd,buf + n,size)) > 0 || errno == EINTR)
{
size -= n;
if (size <= 0)
break;
}
if (n < 0)
{
printf("write %s\n",strerror(errno));
exit(1);
}
size = 0;
}
}
int main()
{
int lisfd;
if ((lisfd = socket(AF_INET,SOCK_STREAM,0)) < 0)
{
printf("socket %s\n",strerror(errno));
exit(1);
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(OWNPORT);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if ( bind(lisfd,(struct sockaddr*)&servaddr,sizeof(servaddr)) < 0)
{
printf("bind %s\n",strerror(errno));
exit(1);
}
if (listen(lisfd,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);
}
int pid,confd;
for (; ;)
{
errno = 0;
if ((confd = accept(lisfd,(struct sockaddr*)NULL,NULL)) < 0)
{
if (errno == EINTR)
continue;
printf("accept %s\n",strerror(errno));
exit(1);
}
if ((pid = fork()) < 0)
{
printf("fork %s\n",strerror(errno));
exit(1);
}else if (pid == 0)
{
close(lisfd);
writeback(confd);
exit(1);
}
close(confd);
}
return 0;
}
运行: