-
Notifications
You must be signed in to change notification settings - Fork 14
/
socket_server_task.cpp
187 lines (179 loc) · 4.19 KB
/
socket_server_task.cpp
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include "socket_server_task.h"
/* 常量 */
#define DEFAULT_PORT "10004" // 端口
#define MAX_REQUEST 1024 // 接收数据的缓存大小
#define BUF_SIZE 4096 // 发送数据的缓存大小
/*发送标志位*/
bool gb_filled = false;
/*发送的数据*/
char sendMsg[2000000];
/*处理接收客户端连接线程*/
extern DWORD WINAPI Thread_AcceptHand(LPVOID lpParameter);
/*
处理任务的线程
发送图像和等数据
*/
DWORD WINAPI Thread_Task_Send(LPVOID lpParameter);
SOCKET ListenSocket = INVALID_SOCKET;// 监听socket
SOCKET ClientSocket = INVALID_SOCKET;// 连接socket
/*
初始化操作
*/
int SocketInit(void)
{
WSADATA wsaData;
struct addrinfo *result = NULL,
hints;
int iResult;// 保存返回结果
// 初始化Winsock,保证Ws2_32.dll已经加载
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != 0)
{
printf("WSAStartup failed: %d\n", iResult);
return 0;
}
// 地址
ZeroMemory(&hints, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
// 获取主机地址,保证网络协议可用等
iResult = getaddrinfo(NULL, // 本机
DEFAULT_PORT, // 端口
&hints, // 使用的网络协议,连接类型等
&result);// 结果
if (iResult != 0)
{
printf("getaddrinfo failed: %d\n", iResult);
WSACleanup();
return 0;
}
// 创建socket,用于监听
ListenSocket = socket(
result->ai_family, // 网络协议,AF_INET,IPv4
result->ai_socktype, // 类型,SOCK_STREAM
result->ai_protocol);// 通信协议,TCP
if (ListenSocket == INVALID_SOCKET)
{
printf("socket failed: %ld\n", WSAGetLastError());
freeaddrinfo(result);
WSACleanup();
return 0;
}
// 绑定到端口
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
if (iResult == SOCKET_ERROR)
{
printf("bind failed: %d\n", WSAGetLastError());
freeaddrinfo(result);
closesocket(ListenSocket);
WSACleanup();
return 0;
}
printf("bind\n");
freeaddrinfo(result);// reuslt不再使用
// 开始监听
iResult = listen(ListenSocket, SOMAXCONN);
printf("start listen......\n");
if (iResult == SOCKET_ERROR)
{
printf("listen failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
WSACleanup();
return 0;
}
LPVOID lpParameter = NULL;
/*创建线程接收连接*/
CreateThread(
NULL,
0,
Thread_AcceptHand, // 线程函数
(LPVOID)lpParameter, // 将socket作为参数
0,
NULL);
}
/*处理接收客户端连接线程*/
DWORD WINAPI Thread_AcceptHand(LPVOID lpParameter)
{
while (1)
{
// 接收客户端的连接,accept函数会等待,直到连接建立
printf("ready to accept\n");
ClientSocket = accept(ListenSocket, NULL, NULL);
// accept函数返回,说明已经有客户端连接
// 返回连接socket
printf("accept a connetion\n");
if (ClientSocket == INVALID_SOCKET)
{
printf("accept failed: %d\n", WSAGetLastError());
closesocket(ListenSocket);
break;// 等待连接错误,退出循环
}
// 为每一个连接创建一个数据发送的接收线程,
// 使服务端又可以立即接收其他客户端的连接
if (!CreateThread(
NULL,
0,
Thread_Task_Send, // 线程函数
(LPVOID)ClientSocket, // 将socket作为参数
0,
NULL))
{
printf("Create Thread error (%d)", GetLastError());
break;
}
}
// 循环退出,释放DLL。
WSACleanup();
return 0;
}
/*
处理任务的线程
发送图像和等数据
*/
DWORD WINAPI Thread_Task_Send(LPVOID lpParameter)
{
DWORD dwTid = GetCurrentThreadId();
// 获得参数sokcet
SOCKET socket = (SOCKET)lpParameter;
// 为接收数据分配空间
int iResult;
int bytesSent;// 用于保存send的返回值,实际发送的数据的大小
while (1)
{
int tx_num = 0;
while (!gb_filled) //等待数据的装载
{
Sleep(10);
}
bytesSent = send(socket, sendMsg, strlen(sendMsg) + 1, 0);
Sleep(10);//ms
if (bytesSent == SOCKET_ERROR)
{
printf("\Thread_Task_Send\tsend error %d\n",
WSAGetLastError());
closesocket(socket);
return 1;
}
gb_filled = false; //数据装载完毕
}
closesocket(socket);
return 0;
}
int packData(vector<double> data) {
int size = data.size();
int slength = 0;
sprintf(sendMsg, "start"); //包头
slength = strlen(sendMsg);
sprintf(sendMsg + slength, ";");
slength = strlen(sendMsg);
sprintf(sendMsg + slength, "%d;", size); //数据数量
slength = strlen(sendMsg);
for (int i = 0; i < size; i++) {
sprintf(sendMsg + slength, "%.10f;", data[i]);
slength = strlen(sendMsg);
}
sprintf(sendMsg + slength, "end");
return strlen(sendMsg);
}