//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处
原文地址:http://my.oschina.net/lngligelang/blog/324479