文章目录
- server和client通信流程图
- 实现两个程序间的通信
- 1.服务端server
- 2.客户端client
- 3.怎么运行呢?
- 4.重写代码
已剪辑自: https://www.cnblogs.com/fisherss/p/12085123.html
server和client通信流程图
在mooc上找到的,使用Socket客户端client和服务端server通信的流程图????
实现两个程序间的通信
1.服务端server
-
服务端需要 "两个"套接字 :
-
1.服务端套接字serverSocket
-
2.客户端connect连接请求时,发来的套接字clientSocket
-
-
按流程图来看, server服务端主要就是实现下面几个步骤:
- 0.WSAStartup初始化 //这个东西也不知道是什么鬼,反正就是要初始化一下,不初始化会创建socket失败!
- 1.服务端套接字 = socket(); //获取一个套接字对象吧?
- 2.bind(服务端套接字); //绑定
- 3.listen(服务端套接字); //监听
—这个时候客户端就可以发连接请求到服务端了,此时服务端会用accept阻塞进程,直到获取客户端发来的请求— - 4.客户端套接字 = accept(); //收到客户端发来的请求,accept返回客户端的套接字对象
- 5.recv(客户端套接字,要发的消息message) //recv会阻塞进程,直到客户端发送消息过来
----printf(message)把接收到的消息打印出来----- - 6.send(客户端套接字,要发的消息message) //服务端也可以使用send,向客户端发送消息
—这里可以循环,跳转回到步骤3.accept 开启新一轮的接收请求— - 7.closesocket(客户端套接字);
所以服务端代码可以这样写????
在CSDN上copy的,原来的代码需要在linux环境下运行,在windows下需要更改很多头文件,和一些函数,wsastartup这个东西也需要初始化一下。
改了之后,一个可以用的服务端server代码????
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135复制 #include <sys/stat.h> #include <fcntl.h> #include <winsock2.h> #include <windows.h> #pragma comment(lib, "wsock32.lib") #include <errno.h> #include<stdlib.h> #include<string.h> #include <sys/types.h> #include<ws2tcpip.h> #include <stdio.h> #include <unistd.h> #define SERVER_PORT 6666 /* 监听后,一直处于accept阻塞状态, 直到有客户端连接, 当客户端如数quit后,断开与客户端的连接 */ int main() { //调用socket函数返回的文件描述符 int serverSocket; //声明两个套接字sockaddr_in结构体变量,分别表示客户端和服务器 struct sockaddr_in server_addr; struct sockaddr_in clientAddr; int addr_len = sizeof(clientAddr); int client; char buffer[200]; //存储 发送和接收的信息 int iDataNum; //必须先初始化 WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) !=2){ printf("require version fail!"); return -1; } //socket函数,失败返回-1 //int socket(int domain, int type, int protocol); //第一个参数表示使用的地址类型,一般都是ipv4,AF_INET //第二个参数表示套接字类型:tcp:面向连接的稳定数据传输SOCK_STREAM //第三个参数设置为0 //建立socket if((serverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) { perror("socket"); return 1; } //初始化 server_addr memset(&server_addr,0, sizeof(server_addr)); //初始化服务器端的套接字,并用htons和htonl将端口和地址转成网络字节序 server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); //ip可是是本服务器的ip,也可以用宏INADDR_ANY代替,代表0.0.0.0,表明所有地址 server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //对于bind,accept之类的函数,里面套接字参数都是需要强制转换成(struct sockaddr *) //bind三个参数:服务器端的套接字的文件描述符, if(bind(serverSocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("connect"); return 1; } //设置服务器上的socket为监听状态 if(listen(serverSocket, 5) < 0) { perror("listen"); return 1; } //循环 接收消息、发送消息 while(1) { printf("监听端口: %dn", SERVER_PORT); //调用accept函数后,会进入阻塞状态 //accept返回一个套接字的文件描述符,这样服务器端便有两个套接字的文件描述符, //serverSocket和client。 //serverSocket仍然继续在监听状态,client则负责接收和发送数据 //clientAddr是一个传出参数,accept返回时,传出客户端的地址和端口号 //addr_len是一个传入-传出参数,传入的是调用者提供的缓冲区的clientAddr的长度,以避免缓冲区溢出。 //传出的是客户端地址结构体的实际长度。 //出错返回-1 client = accept(serverSocket, (struct sockaddr*)&clientAddr, (socklen_t*)&addr_len); if(client < 0) { perror("accept"); continue; } printf("等待消息...n"); //inet_ntoa ip地址转换函数,将网络字节序IP转换为点分十进制IP //表达式:char *inet_ntoa (struct in_addr); printf("IP is %sn", inet_ntoa(clientAddr.sin_addr)); //把来访问的客户端的IP地址打出来 printf("Port is %dn", htons(clientAddr.sin_port)); while(1) { buffer[0] = ''; iDataNum = recv(client, buffer, 1024, 0); if(iDataNum < 0) { // perror("recv null"); continue; } buffer[iDataNum] = ''; if(strcmp(buffer, "quit") == 0) break; printf("收到消息: %sn", buffer); printf("发送消息:"); scanf("%s", buffer); send(client, buffer, strlen(buffer), 0); //服务端也向客户端发送消息 if(strcmp(buffer, "quit") == 0) break; //输入quit停止服务端程序 } } close(serverSocket); return 0; }
2.客户端client
- 客户端只需要 "1个"套接字 :
- 1.服务端套接字serverSocket
- 按流程图来看, client客户端主要就是实现下面几个步骤:
- 0.WSAStartup初始化 //这个东西也不知道是什么鬼,反正就是要初始化一下,不初始化会创建socket失败!
- 1.服务端套接字 = socket(); //获取一个套接字对象
- 2.connect(服务端套接字); //connect连接服务端
—这个时候客户端就可以发数据到服务端了,此时服务端会用recv阻塞进程,直到获取客户端发来的数据— - 3.send(服务端套接字,要发的消息message)
- 4.recv(服务端套接字,收到的message) //客户也可以用recv收消息的,recv会阻塞进程,直到服务端发送消息过来
—printf(message)把接收到的消息打印出来—
—这里可以循环,跳转回到步骤3.send 开启新一轮的接收请求— - 5.closesocket(客户端套接字);
也是在CSDN上copy的代码,改了之后,一个可以用的客户端client代码????
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76复制#include <sys/stat.h> #include <fcntl.h> #include <winsock2.h> #include <windows.h> #pragma comment(lib, "wsock32.lib") #include <errno.h> #include<stdlib.h> #include<string.h> #include <sys/types.h> #include<ws2tcpip.h> #include <stdio.h> #include <unistd.h> #define SERVER_PORT 6666 int main() { //客户端只需要一个套接字文件描述符,用于和服务器通信 int serverSocket; //描述服务器的socket struct sockaddr_in serverAddr; char sendbuf[200]; //存储 发送的信息 char recvbuf[200]; //存储 接收到的信息 int iDataNum; //下面代码初始化 WSADATA wsaData; WSAStartup(MAKEWORD(2,2),&wsaData); if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) !=2){ printf("require version fail!"); return -1; } if((serverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP)) < 0) { perror("socket"); return 1; } serverAddr.sin_family = AF_INET; serverAddr.sin_port = htons(SERVER_PORT); //指定服务器端的ip,本地测试:127.0.0.1 //inet_addr()函数,将点分十进制IP转换成网络字节序IP serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); if(connect(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) { perror("connect"); return 1; } printf("连接到主机...n"); while(1) { printf("发送消息:"); scanf("%s", sendbuf); printf("n"); send(serverSocket, sendbuf, strlen(sendbuf), 0); //向服务端发送消息 if(strcmp(sendbuf, "quit") == 0) break; printf("读取消息:"); recvbuf[0] = ''; iDataNum = recv(serverSocket, recvbuf, 200, 0); //接收服务端发来的消息 recvbuf[iDataNum] = ''; printf("%sn", recvbuf); } close(serverSocket); return 0; }
3.怎么运行呢?
首先编译server.c和client.c这两个c语言,build-compile成.exe文件
用devcpp编译器也可以编译的,不一定一定要用codeblock。。
如果用devcpp上面的代码编译出错,需要把devcpp设置一下编译选项,参考链接
主要运行步骤????
0.确认程序已经编译成功生成了exe文件。
1.先运行服务端server.exe
2.再运行客户端client.exe
3.就可以在client程序里输入消息到服务端了,服务端会收到消息,也能向客户端发消息
这里可以用一下cmd命令符打开运行文件????
运行---->cmd
打开cmd,运行server服务端程序
1
2
3
4复制D: //先进入程序存放的磁盘,比如 D: 或者 C: 或者 F: cd fishers //cd C语言程序服务端server所在的目录,比如cd 2017xxx/MyTest server //直接输入服务端程序的名称,运行server.exe程序,
打开cmd,运行client客户端程序
1
2
3
4复制D: //先进入程序存放的磁盘,比如 D: 或者 C: 或者 F: cd fishers //cd C语言程序客户端client所在的目录,比如cd 2017xxx/MyTest client //直接输入客户端程序的名称,运行client.exe程序
然后就可以在client上输入想要发送的消息了????
按步骤来的视频,配置编译器,编译,运行server.exe,运行client.exe,发消息????
主要是理解客户端和服务端通信的流程
4.重写代码
然后上面是CSDN的代码,理解原理后就可以自己改写server.c和client.c,实现两个程序间基于socket的通信
理解原理:https://blog.csdn.net/jinmie0193/article/details/78951055
server.c????
client.c????
最后
以上就是认真身影最近收集整理的关于C语言Socket编程,实现两个程序间的通信server和client通信流程图实现两个程序间的通信的全部内容,更多相关C语言Socket编程,实现两个程序间内容请搜索靠谱客的其他文章。
发表评论 取消回复