服务端
复制代码
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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152#if 1 #define _WINSOCK_DEPRECATED_NO_WARNINGS #include<iostream> #include<WinSock2.h> #include <ws2tcpip.h> #include <conio.h> #include <cstdio> #include<windows.h> #pragma warning(disable: 4996) #pragma comment(lib, "ws2_32.lib") using namespace std; #define MaxBufSize 1024 void Menu(); int x = 0; DWORD WINAPI Server_send(LPVOID IpParameter); DWORD WINAPI Clinet_recv(LPVOID IpParameter) { char RecvBuf[MaxBufSize] = ""; SOCKET *Client_recv = (SOCKET *)IpParameter; HANDLE Server_send_del = CreateThread(NULL, 0, &Server_send, Client_recv, 0, NULL); while (true) { if (recv(*Client_recv, RecvBuf, MaxBufSize, 0) > 0) { if (!strcmp(RecvBuf, "bye") || !strcmp(RecvBuf, "再见") || !strcmp(RecvBuf, "quit")) { break; } cout << "接收到的消息是:" << RecvBuf << " 来自客户端:" << *Client_recv << endl; memset(RecvBuf, 0, sizeof(RecvBuf)); } } closesocket(*Client_recv); CloseHandle(Server_send_del); x = *Client_recv; cout << "客户端 "<< *Client_recv <<" 断开连接" << endl; return 0; } DWORD WINAPI Server_send(LPVOID IpParameter) { char SendBuf[MaxBufSize] = "", info[1024]; SOCKET *Serve_send = (SOCKET*)IpParameter; while (true) { cin >> info; if (x == *Serve_send) break; if (x == -1) { cout << "断开连接" << endl; closesocket(*Serve_send); return 0; } strcat(SendBuf, info); memset(info, 0, sizeof(info)); cout << "向客户端 " << *Serve_send << " 发送消息" << endl; if (send(*Serve_send, SendBuf, MaxBufSize, 0) < 0) { cout << "发送失败" << endl; } memset(SendBuf, 0, sizeof(SendBuf)); } closesocket(*Serve_send); return 0; } void Stop(SOCKET &sockSER) { closesocket(sockSER); WSACleanup(); cout << "服务器已关闭" << endl; } void start(SOCKET & socketSER) { WSADATA wsadata; //一种数据结构。这个结构被用来存储被WSAStartup函数调用后返回的Windows Sockets数据。它包含Winsock.dll执行的数据。 sockaddr_in addrServer; if (WSAStartup(MAKEWORD(2, 2), &wsadata)) exit(0); socketSER = socket(AF_INET, SOCK_STREAM, 0); addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY); addrServer.sin_family = AF_INET; addrServer.sin_port = htons(7000); if (bind(socketSER, (SOCKADDR*)&addrServer, sizeof(SOCKADDR)) == SOCKET_ERROR) { cout << "端口绑定错误"; exit(-1); } else cout << "端口绑定成功" << endl; if (listen(socketSER, 10)) { cout << "失败" << endl; exit(-1); } else cout << "监听成功n等待客户端发起连接" << endl; } int accept_Clien(SOCKET &sockSER) { while (true) { sockaddr_in addrClient; SOCKET *serClien = new SOCKET; int len = sizeof(SOCKADDR); *serClien = accept(sockSER, (SOCKADDR *) &addrClient, 0); cout << "客户端已连接到服务器,ip是:" << inet_ntoa(addrClient.sin_addr) << " 句柄值是" << *serClien << endl; if (*serClien == -1) { cout << "连接失败" << endl; } CreateThread(NULL, 0, &Clinet_recv, serClien, 0, NULL); } return 0; } void Menu() { printf("------网络通信服务器端------n"); printf("1、启动服务器n2、开始接受客户端连接n3、关闭服务器n4、返回主菜单n5、退出系统n可进行多客户端通信n"); } int main(int argc, char ** argv) { SOCKET socketSER; int Choose; Menu(); while (true) { if (x == -1) { cout << x; } cin >> Choose; switch (Choose) { case 1: start(socketSER); break; case 2: accept_Clien(socketSER); break; case 3: Stop(socketSER); break; case 5: exit(0); break; case 4: system("cls"); Menu(); break; default: printf("输入错误!!请重新输入。n"); } } } #endif
客户端
复制代码
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#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include<string> #include<WinSock2.h> #pragma warning(disable:4996) #pragma comment (lib,"ws2_32.lib") using namespace std; const int PORT = 7000; #define MaxBufSize 1024 #define _CRT_SECURE_NO_WARINGS //监听来自服务器的消息 DWORD WINAPI recvFromServer(LPVOID lpParameter) { char RecvBuf[MaxBufSize]; SOCKET *ClientSocket = (SOCKET*)lpParameter; while (true) { memset(RecvBuf, '', sizeof(RecvBuf)); if (recv(*ClientSocket, RecvBuf, MaxBufSize, 0) > 0) { std::cout << "自服务器接收到信息 " << RecvBuf << "n"; } } return 0; } void Stop(SOCKET &SocketClient) { closesocket(SocketClient); WSACleanup(); std::cout << "客户机关闭" << std::endl; } int Start(SOCKET &SocketClient) { WSADATA wsd; WSAStartup(MAKEWORD(2, 2), &wsd); SocketClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); SOCKADDR_IN ClientAddr; ClientAddr.sin_family = AF_INET; ClientAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); ClientAddr.sin_port = htons(PORT); int n = 0; n = connect(SocketClient, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr)); if (n == SOCKET_ERROR) { cout << "连接失败" << endl; return -1; } cout << "已经连接到服务器" << endl; return 0; } void Client_send(SOCKET &SocketClient) { CreateThread(NULL, 0, &recvFromServer, &SocketClient, 0, NULL); char info[1024], SendBuff[MaxBufSize] = ""; cout << "请输入要发送的信息,按回车结束发送:" << endl; while (1) { cin >> info; strcat(SendBuff, info); memset(info, 0, sizeof(info)); send(SocketClient, SendBuff, sizeof(SendBuff), 0); if (!strcmp(SendBuff, "bye") || !strcmp(SendBuff, "再见") || !strcmp(SendBuff, "quit")) { system("cls"); Stop(SocketClient); break; } memset(SendBuff, 0, sizeof(SendBuff)); } closesocket(SocketClient); WSACleanup(); } void Menu() { cout << "1、启动客户机n2、开始对话n3、关闭客户机 n4、打开菜单n" << endl; } int main() { SOCKET SocketClient; int Choose; Menu(); while (true) { cin >> Choose; switch (Choose) { case 1: Start(SocketClient); break; case 2: Client_send(SocketClient); break; case 3: Stop(SocketClient); exit(0); break; case 4: system("cls"); Menu(); break; default: printf("输入错误!!请重新输入。n"); } } return 0; }
因为线程回调的问题我没有搞清楚,所以服务端的断开连接没有做。只能是客户端断开,我使用句柄值标记客户机,而不是ip。因为这是一个本机的模拟tcp通信的简陋黑框互动,会有回环地址的问题。
代码思路非常简单,服务端创建一个socket接受客户端连接请求。服务端中创建一个接受线程,在接受线程中创建一个发送线程。
客户端创建一个接受线程。
最后
以上就是唠叨丝袜最近收集整理的关于c语言实现socket 多线程 并行的全部内容,更多相关c语言实现socket内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复