惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
S
Securelist
MyScale Blog
MyScale Blog
Jina AI
Jina AI
罗磊的独立博客
The Cloudflare Blog
美团技术团队
博客园 - 叶小钗
阮一峰的网络日志
阮一峰的网络日志
博客园 - 三生石上(FineUI控件)
月光博客
月光博客
雷峰网
雷峰网
小众软件
小众软件
aimingoo的专栏
aimingoo的专栏
大猫的无限游戏
大猫的无限游戏
博客园 - Franky
博客园 - 聂微东
Y
Y Combinator Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
MongoDB | Blog
MongoDB | Blog
T
Tailwind CSS Blog
Attack and Defense Labs
Attack and Defense Labs
博客园_首页
Latest news
Latest news
Apple Machine Learning Research
Apple Machine Learning Research
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Hacker News
The Hacker News
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
P
Proofpoint News Feed
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
U
Unit 42
D
Docker
Webroot Blog
Webroot Blog
N
Netflix TechBlog - Medium
T
Tor Project blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
The Last Watchdog
The Last Watchdog
B
Blog
Recent Announcements
Recent Announcements
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
Security Latest
Security Latest
V2EX - 技术
V2EX - 技术
N
News | PayPal Newsroom
Microsoft Security Blog
Microsoft Security Blog

博客园 - 程序猿101

2024年总结。。。。2025年规划。 八皇后问题c语言版(xcode下通过) 对分布式一些理解 观察者模式 用redis实现悲观锁(后端语言以php为例) 只用200行Go代码写一个自己的区块链!(转) 用户中心 - 博客园 php的生命周期的概述 mysql 慢查询 2016年终总结。。。六年从创业到技术的历程 Linux下chkconfig命令详解 这个简单明了啊 JS的prototype和__proto__ Constructor vagrant homestead laravel 编程环境搭建 发现一个百度的密码。。。记最近一段时间的php感想 mysql 的简单优化 百度面试题 字符串相似度 算法 similar_text 和页面相似度算法 百度的面试题 合并两个有序的数组 PHP性能优化工具–xhprof安装 Ecshop :后台添加新功能 菜单及 管理权限 配置
linux网络编程1 最简单的socket编程
程序猿101 · 2017-03-09 · via 博客园 - 程序猿101

下面是socket编程的服务器端

先看一个图,1

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<unistd.h>   //针对系统调用的封装    fork,pipe 各种i/o原语 read write 等
 5 
 6 #include<sys/socket.h>
 7 #include<netinet/in.h>    //互联网地址族   定义数据结构sockaddr_in
 8 #include<arpa/inet.h>   //提供IP地址转换函数
 9 
10 #include<ctype.h>    //一批C语言字符分类函数 用    于 测试字符是否属于特定的字符类别  topper()在这里
11 
12 #define MAXLINE 80
13 #define SER_PORT 8000
14 
15 int main(void){
16 
17     struct sockaddr_in servaddr,cliaddr;
18     socklen_t cliaddr_len;
19 
20     int listenfd,connfd;
21     char buf[MAXLINE];
22     char str[INET_ADDRSTRLEN];
23     int i,n;
24     char tt[] = "exit1";   //这里有字符数组和字符指针的区别的坑 具体百度查询
25     char *bb;
26 
27     listenfd = socket(AF_INET,SOCK_STREAM,0);  //   
28                                                 //  domain 协议域    AF_INET AF_INET6,AF_LOCAL(AF_UNIX) AF_ROUTE   
29                                                 //  type socket类型   SOCK_STREAM(流式socket 针对tcp )  SOCK_DGRAM(数据包  针对udp) SOCK_RAW 
30                                                 // protocol  协议  tcp协议,udp协议  stcp协议 tipc协议
31 
32     bzero(&servaddr,sizeof(servaddr));   //初始化赋值为0
33 
34     servaddr.sin_family = AF_INET;
35     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);   //任何ip   //这里是大小端的 转换问题。。可以 百度
36     servaddr.sin_port = htons(SER_PORT);     //端口
37 
38     bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));   //绑定链接的套接字描述符  和  地址和端口
39 
40     listen(listenfd,20);
41 
42     printf("Accepting connections ... \n ");
43     while(1){
44 
45         cliaddr_len = sizeof(cliaddr);
46         connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len);  //连接的套接字描述符    返回链接的地址   返回地址的缓冲区长度
47             
48                                                                             //返回  客户端的套接字描述符
49         printf("connfd:%d------\n",connfd);
50 
51         printf("received from %s at PORT %d \n",
52                 inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),
53                 ntohs(cliaddr.sin_port));
54         while(1){
55             n = read(connfd,buf,MAXLINE);    //  read(int fd,void *buf, size_t count);    成功返回  读取的字节数   数据保存在buf上   读取客户端的数据
56 
57             printf("%d,")
58             //printf("buf:%s-----%d\n",buf,strcmp(buf,"exit1"));
59             //printf("tt:%s-----%d\n",tt,strcmp(tt,"exit1"));
60             for(int i=0;i<5;i++){
61                 tt[i] = buf[i];
62             }
63             printf("tt:%s-----%d\n",tt,strcmp(tt,"exit1"));
64             if(strcmp(tt,"exit1") == 0){      //strcmp  对比的就是字符
65                 close(connfd);
66                 printf("close:-----\n");
67                 break;
68             }
69 
70             for(i=0; i < n; i++){
71                 buf[i] = toupper(buf[i]);
72             }
73             write(connfd,buf,n);   //   // 向客户端写入数据   
74         }                                                                           
75         
76     }
77 
78     return 0;                       
79 
80 }
81 
82 //这个程序有漏洞,如果客户端断线或者关闭,服务器就会死循环。   客户端的标准输入是阻塞的。。。其他都不是阻塞的。

客户端

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<unistd.h>
 5 
 6 #include<sys/socket.h>
 7 #include<netinet/in.h>
 8 #include<arpa/inet.h>
 9 
10 #include<errno.h>  //错误
11 
12 #define MAXLINE 80
13 #define SER_PORT 8000
14 
15 int main(int argc,char *argv[]){
16 
17 
18     struct sockaddr_in servaddr;
19     char buf[MAXLINE];
20 
21     int sockfd,n;
22     char *str;
23     char tt[5];
24 
25     //if(argc != 2){
26        // fputs("usage: ./client message \n ",stderr);
27        // exit(1);
28     //}
29 
30     //str = argv[1];
31 
32     sockfd = socket(AF_INET,SOCK_STREAM,0);
33 
34     bzero(&servaddr,sizeof(servaddr));
35     servaddr.sin_family = AF_INET;
36     inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);
37     servaddr.sin_port = htons(SER_PORT);
38 
39     if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0){
40             printf("connet error:%s\n",strerror(errno));
41         }   //链接服务器
42 
43     while(1){
44         
45         memset(buf,0,MAXLINE);
46         printf("client connet server ...\n");
47         n = read(STDIN_FILENO,buf,MAXLINE);   //从标准输入  读取数据
48         for(int i=0;i<5;i++){
49                 tt[i] = buf[i];
50             }
51         if(strcmp(tt,"exit1") == 0){
52             printf("exit server connect \n");
53             close(sockfd);
54             return 0;
55         }
56 
57         write(sockfd,buf,n);   //把我们的输入,写到服务器
58 
59         if(strcmp(tt,"exit1") == 0){
60             printf("exit server connect \n");
61             close(sockfd);
62             return 0;
63         }
64 
65         n = read(sockfd,buf,MAXLINE);    //从服务器读取数据
66 
67 
68         printf("Response from server:\n");
69         write(STDOUT_FILENO,buf,n);   //写到标注输出上
70         printf("\n");
71     }
72     
73     close(sockfd);
74     return 0;
75 
76 }

实验结果:

总结:一个socket建立一个连接,必须配合一个connect,对应的服务器端对应一个accept 。不能多次connet,多次是之后会报错,也不能同一个客户端socket多次accept,因为服务器已经有了,accept会阻塞等待其他客户端的socket。