解决粘包问题的readline function的回射客户端,服务器
-
/*解决粘包问题*/
-
#include<stdio.h>
-
#include<sys/types.h>
-
#include<string.h>
-
#include<sys/socket.h>
-
#include<unistd.h>
-
#include<stdlib.h>
-
#include<signal.h>
-
#include<errno.h>
-
#include<netinet/in.h>
-
#include<arpa/inet.h>
-
#define MAXLINE 1024
-
void die(char *s)
-
{perror(s);
-
exit(0);
-
}
-
/*readn*/
-
ssize_t readn(int fd, void *buf,size_t count)
-
{
-
size_t nleft=count;
-
ssize_t nread;
-
char *bufp=(char*)buf;
-
while(nleft>0)
-
{
-
if((nread=read(fd,bufp,nleft))<0)
-
{
-
if(errno==EINTR)
-
continue;
-
return -1;
-
}
-
else if(nread==0)
-
return count-nleft;
-
bufp+=nread;
-
nleft-=nread;
-
}
-
return count;
-
-
}
-
/*writen*/
-
ssize_t writen(int fd,void* buf,size_t count)
-
{
-
size_t nleft=count;
-
ssize_t nwrite;
-
char *bufp=(char*)buf;
-
while(nleft>0)
-
{
-
if((nwrite=write(fd,bufp,nleft))<0)
-
{
-
if(errno==EINTR)
-
continue;
-
return -1;
-
}
-
else if(nwrite==0)
-
continue;
-
bufp+=nwrite;
-
nleft-=nwrite;
-
}
-
return count;
-
}
-
/*recv_peek function*/
-
ssize_t recv_peek(int sockfd,void*buf,size_t len)
-
{
-
while(1)
-
{
-
int ret=recv(sockfd,buf,len,MSG_PEEK);
-
if(ret==-1&errno==EINTR)
-
continue;
-
return ret;
-
-
}
-
}
-
/*readline function*/
-
ssize_t readline(int sockfd,void *buf,size_t len)
-
{
-
int ret;
-
int nread;
-
char *bufp=buf;
-
int nleft=MAXLINE;
-
while(1)
-
{
-
ret=recv_peek(sockfd,bufp,nleft);
-
if(ret<0)
-
return ret;
-
else if(ret==0)
-
return ret;
-
nread=ret;
-
int i;
-
for(i=0;i<nread;i++)
-
{
-
if(bufp[i]=='\n')
-
{
-
ret=readn(sockfd,bufp,i+1);
-
if(ret!=i+1)
-
exit(1);
-
return ret;
-
}
-
}
-
if(nread>nleft)
-
exit(1);
-
nleft-=nread;
-
ret=readn(sockfd,bufp,nread);
-
if(ret!=nread)
-
exit(1);
-
bufp+=nread;
-
}
-
return -1;
-
}
-
-
void do_service(int conn)
-
{
-
char recvbuf[1024];
-
while(1)
-
{ memset(recvbuf,0,sizeof(recvbuf));
-
int ret=readline(conn,recvbuf,1024);
-
if(ret==-1)
-
die("readline");
-
if(ret==0)
-
{
-
printf("client close\n");
-
break;
-
}
-
fputs(recvbuf,stdout);
-
writen(conn,recvbuf,strlen(recvbuf));
-
}
-
}
-
int main(void)
-
{ /*signal处理僵尸进程*/
signal(SIGCHLD,SIG_IGN);
-
/*socket*/
-
int listenfd;
-
if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
-
die("socket");
-
/*bind*/
-
struct sockaddr_in servaddr;
-
memset(&servaddr,0,sizeof(servaddr));
-
servaddr.sin_family=AF_INET;
-
servaddr.sin_port=htons(5188);
-
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
-
/*servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"");*/
-
/* if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) */
-
int yes=1;
-
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
-
die("reuseaddr");
-
if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
-
die("bind");
-
/*listen*/
-
if(listen(listenfd,SOMAXCONN)<0)
-
die("listen");
-
/*accept*/
-
struct sockaddr_in peeraddr;
-
socklen_t peerlen=sizeof(peeraddr);
-
int conn;
-
/*fork 创建多个进程*/
-
pid_t pid;
-
while(1){
-
if((conn=accept(listenfd,(struct sockaddr*)&peeraddr, &peerlen))<0)
-
die("accept");
-
printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
-
/*echo function*/
-
pid=fork();
-
if(pid==-1)
-
die("fork");
if(pid==0)
{
close(listenfd);
do_service(conn);
exit(0);
}
else
close(conn);
}
/*close socket*/
return 0;
}
-
/*echo_client.c*/
-
#include<stdio.h>
-
#include<sys/types.h>
-
#include<string.h>
-
#include<sys/socket.h>
-
#include<unistd.h>
-
#include<stdlib.h>
-
#include<errno.h>
-
#include<netinet/in.h>
-
#include<arpa/inet.h>
-
#define MAXLINE 1024
-
void die(char *s)
-
{perror(s);
-
exit(0);
-
}
-
ssize_t readn(int fd, void *buf,size_t count)
-
{
-
size_t nleft=count;
-
ssize_t nread;
-
char *bufp=(char*)buf;
-
while(nleft>0)
-
{
-
if((nread=read(fd,bufp,nleft))<0)
-
{
-
if(errno==EINTR)
-
continue;
-
return -1;
-
}
-
else if(nread==0)
-
return count-nleft;
-
bufp+=nread;
-
nleft-=nread;
-
}
-
return count;
-
-
}
-
/*writen*/
-
ssize_t writen(int fd,void* buf,size_t count)
-
{
-
size_t nleft=count;
-
ssize_t nwrite;
-
char *bufp=(char*)buf;
-
while(nleft>0)
-
{
-
if((nwrite=write(fd,bufp,nleft))<0)
-
{
-
if(errno==EINTR)
-
continue;
-
return -1;
-
}
-
else if(nwrite==0)
-
continue;
-
bufp+=nwrite;
-
nleft-=nwrite;
-
}
-
return count;
-
}
-
ssize_t recv_peek(int sockfd,void*buf,size_t len)
-
{
-
while(1)
-
{
-
int ret=recv(sockfd,buf,len,MSG_PEEK);
-
if(ret==-1&errno==EINTR)
-
continue;
-
return ret;
-
-
}
-
}
-
/*readline function*/
-
ssize_t readline(int sockfd,void *buf,size_t len)
-
{
-
int ret;
-
int nread;
-
char *bufp=buf;
-
int nleft=MAXLINE;
-
while(1)
-
{
-
ret=recv_peek(sockfd,bufp,nleft);
-
if(ret<0)
-
return ret;
-
else if(ret==0)
-
return ret;
-
nread=ret;
-
int i;
-
for(i=0;i<nread;i++)
-
{
-
if(bufp[i]=='\n')
-
{
-
ret=readn(sockfd,bufp,i+1);
-
if(ret!=i+1)
-
exit(1);
-
return ret;
-
}
-
}
-
if(nread>nleft)
-
exit(1);
-
nleft-=nread;
-
ret=readn(sockfd,bufp,nread);
-
if(ret!=nread)
-
exit(1);
-
bufp+=nread;
-
}
-
return -1;
-
}
-
int main(void)
-
{
-
/*socket*/
-
int sock;
-
if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
-
die("socket");
-
struct sockaddr_in servaddr;
-
memset(&servaddr,0,sizeof(servaddr));
-
servaddr.sin_family=AF_INET;
-
servaddr.sin_port=htons(5188);
-
/* servaddr.sin_addr.s_addr=htonl(INADDR_ANY); */
-
servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
-
/*connect*/
-
if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
-
die("connect");
-
char sendbuf[1024]={0};
-
char recvbuf[1024]={0};
-
while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
-
{
-
writen(sock,sendbuf,strlen(sendbuf));
-
int ret=readline(sock,recvbuf,sizeof(recvbuf));
-
if(ret==-1)
-
die("read");
-
else if(ret==0)
-
{
-
printf("client close\n");
-
break;
-
}
-
fputs(recvbuf,stdout);
-
memset(sendbuf,0,sizeof(sendbuf));
-
memset(recvbuf,0,sizeof(recvbuf));
-
}
-
close(sock);
-
return 0;
-
}
阅读(782) | 评论(0) | 转发(0) |