//client.cpp //这是回射客户端 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> #include <sys/socket.h> #include <errno.h> #define SA struct sockaddr //readline函数 int readline(int fd,char *buf,int sizeline) { printf("我已进入readline\n"); //字符串处理问题 //思考在这里为什么重新定义一个ptr指针?? char c,*ptr; ptr=buf; int n; again: while((n=read(fd,&c,1))>0) { *ptr++=c; if(c==0){ //note difference 0 ‘\0‘ NULL ‘0‘ // it‘s means it up to end the string break; } } if(n<0 && errno==EINTR) { goto again; }else if(n<0) { printf("read出错%s\n",strerror(errno)); } return 0; } //字符回显函数 int str_cli(FILE *f,int fd){ char sendbuf[20],recvbuf[20]; while(fgets(sendbuf,20,f)!=NULL) { sendbuf[strlen(sendbuf)+1]=0; if( write(fd,sendbuf,strlen(sendbuf)+1)<0) { printf("str_cli write 出现错误%s\n",strerror(errno)); exit(0); } printf("send buf is %s%d",sendbuf,strlen(sendbuf)); bzero(sendbuf,20); readline(fd,recvbuf,20); fputs(recvbuf,stdout); }//end while return 0; } /* 在这里我们将服务器的ip地址我们手动输入 1.创建socket 2.connnect */ int main(int argc,char **argv) { if(argc<2) { printf("请输入合理的参数\n"); exit(0); } int listenfd; struct sockaddr_in cliaddr; //create socket listenfd=socket(AF_INET,SOCK_STREAM,0); if(listenfd<0) { printf("创建socket出错%s\n",strerror(errno)); exit(0); } //connect 在这里我们将使用inet_pton来配置ip bzero(&cliaddr,sizeof(cliaddr)); cliaddr.sin_family=AF_INET; cliaddr.sin_port=htons(9877); if(inet_pton(AF_INET,argv[1],&cliaddr.sin_addr)<0) { printf("inet_pton出现错误%s\n",strerror(errno)); exit(0); } if(connect(listenfd,(SA *)&cliaddr,sizeof(cliaddr))<0) { printf("connect 出现错误%s\n",strerror(errno)); exit(0); } printf("我已经成功连接服务器\n"); //向服务器发送数据和回显数据 str_cli(stdin,listenfd); exit(0); return 0; } //server.cpp //这个是回射服务器程序 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <string.h> #include <arpa/inet.h> #include <sys/socket.h> #include <errno.h> #define SA struct sockaddr //回射函数 //从fd读然后写向fd int str_echo(int fd){ printf("进入str_echo\n"); char buf[20]; int n; int myread; again: bzero(buf,20); while( (myread=read(fd,buf,20)) > 0){ // buf[myread]=0; if( (n=write(fd,buf,myread))<0) { printf("写出现错误\n"); exit(0); } printf("server写完%d%s\n",n,buf); bzero(buf,20); //如果在读的过程中出现错误 那么将相应处理之 }//end while printf("end while?????\n"); if(myread<0&&errno==EINTR) //忽略 { printf("ooops\n"); goto again; }else if(myread<0) { printf("读出现错误%s\n",strerror(errno)); exit(0); }else if(myread==0) { printf("ooooo返回0\n"); } return 0; } int main(int argc,char **argv){ int listenfd,connfd; socklen_t cliins; pid_t childpid; struct sockaddr_in serin,cliin; /* 1.创建socket 2.bind (sockaddr_in的相关初始化) 3.listen 4.accpet */ listenfd=socket(AF_INET,SOCK_STREAM,0); //在服务器中往往只创建一个listenfd套接字 if(listenfd<0){ //他将会在全局存在 printf("socket创建失败%s\n",strerror(errno)); exit(0); } bzero(&serin,sizeof(serin)); serin.sin_family=AF_INET; serin.sin_port=htons(9877); serin.sin_addr.s_addr=htonl(INADDR_ANY); //bind if(bind(listenfd,(SA *)&serin,sizeof(serin))<0) { printf("bind创建失败%s\n",strerror(errno)); exit(0); } //listen listen(listenfd,5); //accpet //note this 我们传入cliins的值 cliins=sizeof(cliin); //在这里我们将fork一个进程来接收新的请求 for(;;){ connfd=accept(listenfd,(SA *)&cliin,&cliins); if(connfd<0){ printf("accpet 创建失败%s\n",strerror(errno)); exit(0); } printf("链接已经建立\n"); if((childpid=fork())<0) { printf("创建进程失败\n"); exit(0); }else if(childpid==0) { //child printf("子进程已建立\n"); close(listenfd); //调用回显函数 str_echo(connfd); printf("子进程已做相关处理\n"); exit(0); } //parent close(connfd); }// end for return 0; } /////////////////////////////////////////////////////////////////note//////////////////////////////////////////////////////////////////////////////// 我们在这里需要注意的是相关IO的处理问题 比如说char a[50]; 当我第一次写a="www.baidu.com" 第二次写如数据www.sina.com若最后没有添加0或‘\0’或NULL 那么他将只会覆盖前面几个字符 然后一直读到www.baidu.com的0处
时间: 2024-11-05 06:58:25