在上個文章中,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;
}
希望和各位共同進步,如有錯誤,歡迎指正。