Linux下的socket通信小程序分享

发表于:2014-10-30 09:58

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:第三圣子    来源:51Testing软件测试网采编

分享:
  下边是客户端代码:
1 #include <mylib.h>
2 int main(void)
3 {
4     int sock_fd;
5     sock_fd=socket(AF_INET,SOCK_STREAM,0);
6
7     struct sockaddr_in serv_add;
8     bzero(&serv_add,sizeof(serv_add));
9     serv_add.sin_family=AF_INET;
10     serv_add.sin_port=htons(SERV_PORT);
11     struct in_addr add;
12     inet_aton("192.168.1.105",&add);
13     serv_add.sin_addr=add;
14
15     if(connect(sock_fd,(struct sockaddr *)&serv_add,sizeof(serv_add))<0)
16         sys_err("connect error!\n");
17     char sendbuff[MAXLINE],recvbuff[MAXLINE];
18     char *temp;
19     ssize_t n;
20     while ((temp=fgets(sendbuff,sizeof(sendbuff),stdin)) !=NULL)
21     {
22         int k;
23         if((k=write(sock_fd,sendbuff,sizeof(sendbuff)))<0)
24         {
25
26         }
27         if((n=read(sock_fd,recvbuff,sizeof(recvbuff)))>0)
28             printf("SVR:%s",recvbuff);
29         if(n<0)
30             printf("fail to get data from server %s\n",inet_ntoa(serv_add.sin_addr));
31         if(n==0)
32         {
33             //broken pipe ,haha  sigpipe
34             printf("%s","server defunct\nclosing the socket...");
35             close(sock_fd);
36         }
37     }
38     return 0;
39 }
  解释一下客户端代码:
  第5行:sock_fd=socket(AF_INET,SOCK_STREAM,0); 用socket函数创建一个sock,第一个参数是协议族,我们用AF_INET代表tcp/ip协议族。第二个参数代表流方式,也就是TCP 字节流方式。第三个参数,额...貌似有点高深,说实话,不懂,注释说 If it is zero,  is chosen automatically.  就是自动选择,我擦,这一自动,我感觉整个人都不舒服了...
  行7:struct sockaddr_in serv_add;  定义一个sock 地址结构,用来存放服务器断ip,端口,协议族之类的。
  行10,12:这两行里都有一个来处理端口和ip,为啥,这里牵扯一个“字节序”的问题,处理器对字节的排列顺序不是相同的,这个可以百度以下,呵呵
  行15:用本地初始化的sock和服务端地质结构建立连接。等等,为啥客户端sock没有地址和端口呢,怎么直接就连接了,这不科学。额,就这在这一不,tcp默认将本地sock地址设为本地ip,端口在允许范围内随机取值,一般不会是vip端口(<1024)啦。而且每次链接都会随机端口。好,地址设好就可以连接服务器了,进行关键的三次握手。
  行20,23:从输入设备读取 输入值。写入打开的 socket 文件符。将输入值 写入建好的 pipe里。这里的write为什么回有小于0的情况呢,原因是,当服务起进程断开连接,或者不小心关闭时,服务端乎发给客户端一个FIN,表示终止链接,但是由于TCP是半关闭的,客户端可能正在输入,不知道服务端已经断开了,服务端TCP会返回一个RST,告诉客户端管道不通。这时如果继续将值写入pipe,系统就会立马提示你 管道断裂,发一个SIGPIPE信号给你。这个信号很要命啊,你不捕获处理,系统就默认关掉你的进程。处理了,write就返回小于0
  行27:读取服务器的返回值,读取失败就返回小于0
  行31:同样,服务断断开后,客户端已收到FIN的通知,read后直接返回0. 这里为了不让出现23行的问题,干脆把socket关闭了
  下边是服务端代码:
1 #include <mylib.h>
2
3 int main(void)
4 {
5     int listen_fd , connected_fd;
6     struct sockaddr_in serv_add;
7 //-----------------------------------------------------------------------------
8     listen_fd=socket(AF_INET,SOCK_STREAM,0);
9     serv_add.sin_family=AF_INET;
10     serv_add.sin_port=htons(SERV_PORT);
11     serv_add.sin_addr.s_addr=htonl(INADDR_ANY);
12 //------------------------------------------------------------------------------
13     if(bind(listen_fd,(struct sockaddr *)&serv_add,sizeof(serv_add))<0)
14         sys_err("bind error\n");
15     if(listen(listen_fd,LISTENQ)<0)
16         sys_err("listen error\n");
17
18     signal(SIGCHLD,sig_chld);
19
20     __pid_t pid;
21     while (1) {
22         connected_fd = accept(listen_fd,0,0);
23        if(connected_fd<0){
24         if(errno==EINTR)
25         {
26             printf("interrupt\n");
27             continue;
28         }
29         else
30             sys_err("accept eero!\n");
31        }
32         if((pid=fork())==0)
33         {
34             char recevBuff[MAXLINE];
35             int n;
36             close(listen_fd);
37             while ((n=read(connected_fd,recevBuff,MAXLINE))>0) {
38                 printf("Client:%s",recevBuff);
39                 write(connected_fd,recevBuff,MAXLINE);
40             }
41             if(n<0)
42                 sys_err("read error\n");
43             close(connected_fd);
44             exit(0);
45         }
46         close(connected_fd);
47     }
48     return 0;
49 }
32/3<123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号