解决问题:
服务器进程或主机意外崩溃或重启
输出重定向
客户端代码:
vi c3.c
#include
#include
#include
#include
#include
#include
#include
#include
#define SERV_PORT 9877
#define MAXLINE 4096
void client_echo(FILE *fp,int sockfd)
{
int fd = fileno(fp);
int maxfd = fd > sockfd ? fd : sockfd;
fd_set fs;
FD_ZERO(&fs);
int n;
char buf[MAXLINE];
int ioeof = 0;
for (; ;)
{
if (ioeof == 0)
FD_SET(fd,&fs);
FD_SET(sockfd,&fs);
if (select(maxfd + 1,&fs,NULL,NULL,NULL) < 0)
{
printf("select: %s\n",strerror(errno));
exit(1);
}
if (FD_ISSET(sockfd,&fs))
{
if ((n = read(sockfd,buf,MAXLINE)) == 0)
{
if (ioeof == 1)
return;
else
printf("server is broke\n");
}else if (n < 0)
{
printf("read: %s\n",strerror(errno));
exit(1);
}
if (write(fd,buf,n) != n)
{
printf("write %s\n",strerror(errno));
exit(1);
}
}
if (FD_ISSET(fd,&fs))
{
if ((n = read(fd,buf,MAXLINE)) == 0)
{
ioeof = 1;
if(shutdown(sockfd,SHUT_WR) < 0)
{
printf("shutdown error\n");
exit(1);
}
FD_CLR(fileno(fp),&fs);
continue;
}else if (n < 0)
{
printf("read: %s\n",strerror(errno));
exit(1);
}
if (write(sockfd,buf,n) != n)
{
printf("write: %s\n",strerror(errno));
exit(1);
}
}
}
}
int main(int argc,char **argv)
{
if (argc != 2)
{
printf("please add \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(SERV_PORT);
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);
}
client_echo(stdout,sockfd);
}
服务器代码:
vi s3.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;
}