设为首页 收藏本站
查看: 256|回复: 0

[经验分享] linux-网络编程-TCP多进程C/S

[复制链接]

尚未签到

发表于 2016-3-23 09:21:36 | 显示全部楼层 |阅读模式
  
  开2个终端窗口:
  1)
  deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcpc
  client send....
  client send :deepfuture.iyunv.com
  
  client read :hello
  
  deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcpc
  client send....
  client send :deepfuture.iyunv.com
  
  client read :hello
  
  deepfuture@deepfuture-laptop:~/private/mytest$ 




2)

deepfuture@deepfuture-laptop:~/private/mytest$ ./testtcps

server wait....

server wait....




server read :deepfuture.iyunv.com




server send :hello

server wait....




server read :deepfuture.iyunv.com




server send :hello

二、客户端






#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//deepfuture.iyunv.com
ssize_t readn(int fd,void *ptr,size_t maxcn){//读取n个字符,maxc为读取的数目
size_t noreadcn,readcn;
char *buf=ptr;

noreadcn=maxcn;
while(noreadcn>0){
if ( (readcn=read(fd,buf,noreadcn))<0){//读数据
if (errno==EINTR) {//数据读取前,操作被信号中断 deepfuture.iyunv.com
perror("中断错误");
readcn=0;            
}
else {return -1;}//无法修复错误,返回读取失败
}
else if(readcn==0) break;//EOF deepfuture.iyunv.com
noreadcn-=readcn;//读取成功,但是如果读取的字符数小于maxc,则继续读,因为可能数据还会继续通过网络送过来   
buf+=readcn;   
if (*buf==0) break;    //如果读到字符串结尾标志则退出,必须有这句,否则会死循环  deepfuture.iyunv.com
}   
return (maxcn-noreadcn);
}
ssize_t writen(int fd,void *ptr,size_t maxcn){//写入n个字符
size_t nowritecn,writecn;
char *buf=ptr;
nowritecn=maxcn;
while(nowritecn>0){
if((writecn=write(fd,buf,nowritecn))<=0){//写数据
if (errno==EINTR) {//数据写前,操作被信号中断
perror("中断错误");
writecn=0;            
}
else {return -1;}//无法修复错误,返回读取失败
}
nowritecn-=writecn;
buf+=writecn;
}  
return (maxcn-nowritecn);
}
int main(void){
int fd;
int addresslen;
struct sockaddr_in address;//地址信息结构 deepfuture.iyunv.com
int pid;
char mybuf[100];        
char *buf="deepfuture.iyunv.com\n";
int rc;

fd=socket(AF_INET,SOCK_STREAM,0);//建立socket
if (fd==-1){//错误,类型从errno获得
perror("error");//perror先输出参数,后跟":"加空格,然后是errno值对应的错误信息(不是错误代码),最后是一个换行符。    deepfuture.iyunv.com     
}
printf("client send....\n");
fflush(stdout);
//连接
address.sin_family=AF_INET;//IPV4协议,AF_INET6是IPV6 deepfuture.iyunv.com
address.sin_addr.s_addr=inet_addr("127.0.0.1");//l表示32位,htonl能保证在不同CPU的相同字节序
address.sin_port=htons(1253);//端口号,s表示16位 deepfuture.iyunv.com
addresslen=sizeof(address);        
rc=connect(fd,(struct sockaddr *)&address,addresslen);//连接服务器 deepfuture.iyunv.com
if (rc==-1){//rc=0成功,rc=-1失败 deepfuture.iyunv.com
perror("连接错误");
exit(1);
}
//发送数据
writen(fd,(void *)buf,strlen(buf)+1);
printf("client send :%s\n",buf);      
//读取数据
bzero(mybuf,100);  
readn(fd,(void *)mybuf,100);
printf("client read :%s\n",mybuf);
close(fd);
exit(0);               
}


 服务端

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
//deepfuture.iyunv.com
ssize_t readn(int fd,void *ptr,size_t maxcn){//读取n个字符,maxc为读取的数目
size_t noreadcn,readcn;
char *buf=ptr;

noreadcn=maxcn;
while(noreadcn>0){
if ( (readcn=read(fd,buf,noreadcn))<0){//读数据
if (errno==EINTR) {//数据读取前,操作被信号中断
perror("中断错误");
readcn=0;           
}
else {return -1;}//无法修复错误,返回读取失败
}
else if(readcn==0) break;//EOF

noreadcn-=readcn;//读取成功,但是如果读取的字符数小于maxc,则继续读,因为可能数据还会继续通过网络送过来   
buf+=readcn;  
if (*buf==0) break;//如果读到字符串结尾标志则退出,必须有这句,否则会死循环
}  

return (maxcn-noreadcn);
}
ssize_t  writen(int fd,void *ptr,size_t maxcn){//写入n个字符
size_t nowritecn,writecn;
char *buf=ptr;

nowritecn=maxcn;
while(nowritecn>0){
if((writecn=write(fd,buf,nowritecn))<=0){//写数据
if (errno==EINTR) {//数据写前,操作被信号中断
perror("中断错误");
writecn=0;            
}
else {return -1;}//无法修复错误,返回读取失败
}

nowritecn-=writecn;
buf+=writecn;  
}
return (maxcn-nowritecn);
}
int main(void){
int fd;
int addresslen;
struct sockaddr_in address;//地址信息结构
int pid;
int rc;

//建立socket
fd=socket(AF_INET,SOCK_STREAM,0);//fd为socket
if (fd==-1){//错误,类型从errno获得
perror("error");//perror先输出参数,后跟":"加空格,然后是errno值对应的错误信息(不是错误代码),最后是一个换行符。        
}
//bind 到socket fd   
address.sin_family=AF_INET;//IPV4协议,AF_INET6是IPV6
address.sin_addr.s_addr=htonl(INADDR_ANY);//l表示32位,htonl能保证在不同CPU的相同字节序
address.sin_port=htons(1253);//端口号,s表示16位
addresslen=sizeof(address);

bind(fd,(struct sockaddr *)&address,addresslen);//bind
//建立socket队列,指定最大可接受连接数
rc=listen(fd,32);//最多接收32个连接,开始监听
//int listen(int sockfd, int backlog)返回:0──成功, -1──失败
//内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接
if (rc==-1) {
perror("listen error");//监听失败
exit(1);
}
while(1){
struct sockaddr_in clientaddress;
int address_len;
int client_sockfd;
char mybuf[100];   
char *buf="hello\n";              
//等待连接,使用新的进程或线程来处理连接
printf("server wait....\n");
fflush(stdout);     
address_len=sizeof(clientaddress);
client_sockfd=accept(fd,(struct sockaddr *)&clientaddress,&address_len);//client_sockfd可理解为一个文件句柄,能用read和write操作。client_address是客户端信息结构 deepfuture.iyunv.com
//fork进程来处理每个客户的连接      
pid=fork();
if (pid<0){//错误
printf("error:%s\n",strerror(errno));//strerror将errno映射为一个错误信息串 deepfuture.iyunv.com
close(client_sockfd);
exit(1);
}   
if (pid==0){ //子进程处理每个客户端的数据            
close(fd);//子进程关闭不需要它处理的监听资源
//读取数据 deepfuture.iyunv.com
bzero(mybuf,100);                  
readn(client_sockfd,(void *)mybuf,100);
printf("\nserver read :%s",mybuf);                  
//发送数据                  
writen(client_sockfd,(void *)buf,strlen(buf)+1);               
printf("\nserver send :%s",buf);               
close(client_sockfd);
exit(0);
}
else {//父进程
close(client_sockfd);//父进程不处理客户端连接,因此关闭,但并不意味着把子进程的处理句柄关闭,因为子进程继承了父进程的client_sockfd资源         deepfuture.iyunv.com     
}
}
}
 
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-194547-1-1.html 上篇帖子: linux中删除find找到的文件 下篇帖子: Linux 批量只修改文件或文件夹权限
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表