在上个文章中,tcp服务端有着很多的坑,这次经过改良,用了多线程来实现服务端的编码。
一个线程用于监听客户端的socket,一个用于接收数据。话不多少,直接看代码。
UINT server_thd(LPVOID P)
{
//初始化WinSock 如果没有这段 socket将会一直无连接!!!!!!!!!
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)
{
return 0;
}
sockaddr_in local_addr;
sockaddr_in client_addr;
int addrSize = sizeof(sockaddr_in);
int res;
//char *msgg = new char[1024];
char msg[1024];
local_addr.sin_family = AF_INET; // 互联网地址簇
local_addr.sin_port = htons(8080);//端口
local_addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);//本机IP
// local_addr.sin_addr.S_un.S_addr= inet_addr("192.169.13.183");
//创建socket套接字
//AF_INET 协议簇代表TCP/IP SOCK_STREAM socket类型 IPPROTO_TCP协议类型
listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listen_socket == INVALID_SOCKET)
{
CImformationDlg ImformationDlg("网络初始化失败");
ImformationDlg.DoModal();
return 1;
}
if (bind(listen_socket, (struct sockaddr*) &local_addr, sizeof(SOCKADDR_IN)))
{
CImformationDlg ImformationDlg("网络初始化失败");
ImformationDlg.DoModal();
return 1;
}
listen(listen_socket, 10);// 第二个参数为套接字最大连接数
while (true)
{
sock = accept(listen_socket, (SOCKADDR *)&client_addr, &addrSize);
if (sock == INVALID_SOCKET)
{
WSACleanup();
exit(1);
}
h_RecvThread = CreateThread(nullptr,0,ReceiveThred, (LPVOID)sock,0,nullptr);
if (h_RecvThread == NULL)
{
WSACleanup;
}
CloseHandle(h_RecvThread);
}
//closesocket(listen_socket);
//WSACleanup();
}
DWORD WINAPI ReceiveThred(LPVOID parameter)
{
SOCKET clt_Socket = (SOCKET)parameter;
char msg[1024];
int res = 0;
do
{ //每次先清空
memset(msg, 0, 1024);
res = recv(clt_Socket, msg, 1024, 0);
if (res > 0)
{ //根据个人需求对接收数据进行处理
memcpy(g_SystemParam.RecData, msg, 1024);
::SendMessage(g_SystemParam.m_pOwnerWnd->m_hWnd, IDC_WM_HADRECEIVEDATAOVER, 0, 0);
}
//对recv的返回值res进行判断
else if (res == -1)
{
closesocket(clt_Socket);
return 1;
}
else if (res == 0)
{
break;
}
} while (res>0);
res = shutdown(clt_Socket, SD_SEND);
if (res == SOCKET_ERROR)
{
closesocket(clt_Socket);
return 1;
}
return 0;
}
希望和各位共同进步,如有错误,欢迎指正。