socket编程与利用进程进行多并行连接
时间:2022-05-05
本文章向大家介绍socket编程与利用进程进行多并行连接,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
呈现一张基本的socket阻塞式模型,如下图:
一: 对于一对一的进行C/S回射:
服务端(server.c):
1 #include<unistd.h>
2 #include<stdio.h>
3 #include<string.h>
4 #include<stdlib.h>
5 #include<netinet/in.h>
6 #include<sys/socket.h>
7 #include<sys/types.h>
8 #include<error.h>
9
10 #define ERR_EXIT(m)
11 do{
12 perror(m);
13 exit(1);
14 }while(0)
15
16 int
17 main (void)
18 {
19 int sock, conn;
20 if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
21 ERR_EXIT ("socket");
22 struct sockaddr_in sockaddr;
23 memset (&sockaddr, 0, sizeof (sockaddr));
24 sockaddr.sin_family = AF_INET;
25 sockaddr.sin_port = htons (5528);
26 sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
27 if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)
28 ERR_EXIT ("Bind");
29 if (listen (sock, SOMAXCONN) < 0)
30 ERR_EXIT ("Listen");
31 struct sockaddr_in client;
32 memset (&client, 0, sizeof (client));
33 socklen_t addrlen = sizeof (client);
34 if ((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0)
35 ERR_EXIT ("Accept");
36 char sed[1024], recv[1024];
37 while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1)
38 {
39 if (strlen (sed) > 0)
40 write (conn, sed, sizeof (sed));
41 if (read (conn, recv, sizeof (recv)) > 0)
42 {
43 fputs (recv, stdout);
44 if (strcmp (recv, "exit") == 0)
45 break;
46 write (conn, recv, sizeof (recv));
47 }
48 else
49 ERR_EXIT ("read...");
50 }
51 close (conn);
52 close (sock);
53 return 0;
54 }
客户端(client.c):
1 #include<unistd.h>
2 #include<stdio.h>
3 #include<string.h>
4 #include<error.h>
5 #include<netinet/in.h>
6 #include<stdlib.h>
7 #include<sys/socket.h>
8 #include<sys/types.h>
9
10 #define ERR_EXIT( m )
11 do{
12 perror(m);
13 exit(1);
14 }while(0);
15
16 int
17 main (void)
18 {
19 int socketid, conn;
20
21 if ((socketid = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
22 ERR_EXIT ("socket");
23
24 struct sockaddr_in server_addr;
25 memset (&server_addr, 0, sizeof (server_addr));
26
27 server_addr.sin_family = AF_INET;
28 server_addr.sin_port = htons (5528);
29 server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
30 if ((conn =
31 connect (socketid, (struct sockaddr *) &server_addr,
32 sizeof (server_addr))) < 0)
33 ERR_EXIT ("connect");
34 char sendbuf[1024], recivebuf[1024];
35 while (fgets (sendbuf, sizeof (sendbuf), stdin) != NULL)
36 {
37 write (socketid, sendbuf, sizeof (sendbuf));
38 read (socketid, recivebuf, sizeof (recivebuf));
39 fputs (recivebuf, stdout);
40 if (strcmp (recivebuf, "exit") == 0)
41 {
42 ERR_EXIT ("exit");
43 break;
44 }
45 }
46 close (conn);
47 close (socketid);
48 return 0;
49 }
相关的makefile文件
1 makefile文件:
2
3 .SUFFIXES: .o.c
4 .PHONY: clean
5 .PHONY: start
6
7 CC =gcc
8 SRC =server.c
9 OBJS =$(SRC:.c =.o)
10 BIN = Server
11
12 start:
13 $(CC) -o $(BIN) $(OBJS)
14
15 .o.c:
16 $(CC) -g -Wall $@ -c $<
17 clean:
18 rm -f $(OBJS)
但是上述虽然满足了基本的socket套路,但是当我们关闭服务可执行程序时,在开启就会出现地址被占用,解决此等问题,需再加上一个setsockopt()函数,对齐进行设定。
详细可以去查询man帮助(man setsockopt)
代码:
1 int on = 1;
2 if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
3 {
4 ERR_EXIT ("setsockopt");
5 }
6
7
8 if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)
9 ERR_EXIT ("Bind");
二: 利用进程进行并行socket阻塞式连接:
客户端和makefile文件和上面一样,只是将socket的服务端,修改为调用进程来进行多并发连接即可!
服务端(server.c):
1 #include<unistd.h>
2 #include<stdio.h>
3 #include<string.h>
4 #include<stdlib.h>
5 #include<netinet/in.h>
6 #include<sys/socket.h>
7 #include<sys/types.h>
8 #include<error.h>
9
10 #define ERR_EXIT(m)
11 do{
12 perror(m);
13 exit(1);
14 }while(0)
15
16
17 void
18 print (int conn){
19
20 char sed[1024], recv[1024];
21 while (fgets (sed, sizeof (sed), stdin) != NULL || 1 == 1)
22 {
23 if (strlen (sed) > 0)
24 write (conn, sed, sizeof (sed));
25 if (read (conn, recv, sizeof (recv)) > 0)
26 {
27 fputs (recv, stdout);
28 if (strcmp (recv, "exit") == 0)
29 break;
30 write (conn, recv, sizeof (recv));
31 }
32 else
33 ERR_EXIT ("read...");
34 }
35 close (conn);
36 }
37
38 int
39 main (void)
40 {
41 int sock, conn;
42 if ((sock = socket (PF_INET, SOCK_STREAM, 0)) < 0)
43 ERR_EXIT ("socket");
44 struct sockaddr_in sockaddr;
45 memset (&sockaddr, 0, sizeof (sockaddr));
46 sockaddr.sin_family = AF_INET;
47 sockaddr.sin_port = htons (5528);
48 sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
49
50 int on = 1;
51 if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
52 {
53 ERR_EXIT ("setsockopt");
54 }
55
56
57 if (bind (sock, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)
58 ERR_EXIT ("Bind");
59
60 if (listen (sock, SOMAXCONN) < 0)
61 ERR_EXIT ("Listen");
62
63 struct sockaddr_in client;
64 memset (&client, 0, sizeof (client));
65 socklen_t addrlen = sizeof (client);
66 pid_t pid ;
67
68 while (1)
69 {
70 if((conn = accept (sock, (struct sockaddr *) &client, &addrlen)) < 0)
71 ERR_EXIT ("Accept");
72 pid = fork ();
73 if (pid == -1)
74 ERR_EXIT ("fork");
75 else if (pid == 0){
76 close (sock);
77 print (conn);
78 }
79 else
80 close (conn);
81 }
82 close (sock);
83 return 0;
84 }
- 窗口自动弹出浏览器显示广告的问题
- Instagram 开源用于 Python 3的MonkeyType 工具
- 拼凑了几个自定义的Panel(包括FishEyePanel,WrapPanel等几个常用的布局)
- jquery获取父级一级节点的序号
- Docker容器学习梳理--基础知识(2)
- Blend生成的TransformGroup如何引用?
- 今日头条写新闻机器人获吴文俊人工智能科技发明奖
- Docker容器学习梳理--应用程序容器环境部署
- 异步方式访问网页
- Silverlight:利用Panel实现自定义布局
- 《物联网智能终端信息安全白皮书》再次敲响物联网时代警钟
- Gitlab可视化代码树插件-Octotree
- 子线程调用UI线程的方法
- Silverlight:Dependency Property(依赖属性)学习笔记
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 玩转 Linux 环境下日期的语法
- dubbo学习之事件通知实践
- Panasonic Programming Contest 2020 A ~~C
- 采用递归生成排列
- UCF Local Programming Contest 2015 A~~H
- python之循环控制语句
- python之结合if条件判断和生成随机数的相关知识,完成石头剪刀布的游戏
- AtCoder Beginner Contest 172
- python的import与 from……import
- 题目 1159: [偶数求和]
- 回溯法求组合问题
- P1567 统计天数
- P1089 津津的储蓄计划(模拟训练)
- 二分练习 --D - Trailing Zeroes (III)
- HDU 5806