基于Win32的多线程客户/服务器通信

本文提供了一个简单的客户端-服务器通信实例,展示了如何使用Winsock进行TCP连接建立、数据发送与接收的过程。客户端通过指定服务器地址发起连接请求,并发送字符串数据;服务器监听特定端口,接收客户端数据并进行验证后返回结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

客户端:
//Client.cpp:Definestheentrypointfortheapplication.
//

#include
"stdafx.h"
#include
"resource.h"
#include
<winsock.h>

#pragmawarning(disable:4700)

#defineMAX_LOADSTRING100

//GlobalVariables:
HINSTANCEhInst;//currentinstance
TCHARszTitle[MAX_LOADSTRING];//Thetitlebartext
TCHARszWindowClass[MAX_LOADSTRING];//Thetitlebartext

//Fowarddeclarationsoffunctionsincludedinthiscodemodule:
ATOMMyRegisterClass(HINSTANCEhInstance);
BOOLInitInstance(HINSTANCE,
int);
LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
LRESULTCALLBACKAbout(HWND,UINT,WPARAM,LPARAM);

intAPIENTRYWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTRlpCmdLine,
intnCmdShow)
{
//TODO:Placecodehere.
MSGmsg;
HACCELhAccelTable;

//Initializeglobalstrings
LoadString(hInstance,IDS_APP_TITLE,szTitle,MAX_LOADSTRING);
LoadString(hInstance,IDC_CLIENT,szWindowClass,MAX_LOADSTRING);
MyRegisterClass(hInstance);

//Performapplicationinitialization:
if(!InitInstance(hInstance,nCmdShow))
{
returnFALSE;
}


hAccelTable
=LoadAccelerators(hInstance,(LPCTSTR)IDC_CLIENT);

//Mainmessageloop:
while(GetMessage(&msg,NULL,0,0))
{
if(!TranslateAccelerator(msg.hwnd,hAccelTable,&msg))
{
TranslateMessage(
&msg);
DispatchMessage(
&msg);
}

}


returnmsg.wParam;
}


LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)
{
intwmId,wmEvent;
PAINTSTRUCTps;
HDChdc;
TCHARszHello[MAX_LOADSTRING];
LoadString(hInst,IDS_HELLO,szHello,MAX_LOADSTRING);

WORDversion;
//usedtostorethesocketversion
WSADATAwsaData;//usedtostoreinfoaboutsocket
SOCKETtheSocket;//usedtocreateclientsocket
SOCKADDR_INserverInfo;//usedtospecifyalocalorremoteendpointaddresstowhichtoconnectasocket
intrVal;//usedtostorereturnvalue
LPHOSTENThostEntry;//WindowsSocketsallocatesthisstructure
char*buf="DataOnSocket";//Datatobesendonsocket

chardata[5];
switch(message)
{
caseWM_COMMAND:
wmId
=LOWORD(wParam);
wmEvent
=HIWORD(wParam);
//Parsethemenuselections:
switch(wmId)
{
caseIDM_ABOUT:
DialogBox(hInst,(LPCTSTR)IDD_ABOUTBOX,hWnd,(DLGPROC)About);
break;
caseIDM_EXIT:
DestroyWindow(hWnd);
break;
caseIDM_COMMUNICATE:
//gettheversionofsocket
version=MAKEWORD(1,1);
//TheWindowsSocketsWSAStartupfunctioninitiatesuseofWS2_32.DLLbyaprocess
rVal=WSAStartup(version,(LPWSADATA)&wsaData);
//storeinformationabouttheserver
//Herewearesupposetopasstheserverinformationtotheclient,
//sothattheclientknowswhereistheserver
//Iamusingthemachinenameonwichmyserver.exeisrunning
hostEntry=gethostbyname("seclore3");
if(!hostEntry)
{
MessageBox(hWnd,
"FailedingethostbynameAPI","GethostbynameError",MB_OK);
WSACleanup();
break;
}

//herewearecreatingthesocket
theSocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(theSocket==SOCKET_ERROR)
{
MessageBox(hWnd,
"FailedinsocketAPI","SocketError",MB_OK);
}

//Fillinthesockaddr_instruct
serverInfo.sin_family=PF_INET;
serverInfo.sin_addr
=*((LPIN_ADDR)*hostEntry->h_addr_list);
serverInfo.sin_port
=htons(8888);
//Connecttothesocketwejustcreated
rVal=connect(theSocket,(LPSOCKADDR)&serverInfo,sizeof(serverInfo));
if(rVal==SOCKET_ERROR)
{
MessageBox(hWnd,
"FailedinconnectAPI","ConnectError",MB_OK);
break;
}

//Sendthedatatotheserver
rVal=send(theSocket,buf,strlen(buf),0);
if(rVal==SOCKET_ERROR)
{
MessageBox(hWnd,
"Failedsend","SendError",MB_OK);
}

//Get/Recievethedatasentbytheserver
rVal=recv(theSocket,data,5,0);
if(rVal)
{
MessageBox(hWnd,data,
"Datafromserver",MB_OK);
}

break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}

break;
caseWM_PAINT:
hdc
=BeginPaint(hWnd,&ps);
//TODO:Addanydrawingcodehere
RECTrt;
GetClientRect(hWnd,
&rt);
DrawText(hdc,szHello,strlen(szHello),
&rt,DT_CENTER);
EndPaint(hWnd,
&ps);
break;
caseWM_DESTROY:
//Closethesocket
closesocket(theSocket);
//TheWSACleanupfunctioninitiatesnoaction
WSACleanup();
PostQuitMessage(
0);
break;
default:
returnDefWindowProc(hWnd,message,wParam,lParam);
}

return0;
}


服务器端:

//Server.cpp:Definestheentrypointfortheapplication.
//

#include
"stdafx.h"
#include
"resource.h"
#include
<winsock.h>

//functiondeclaration
DWORDWINAPIValidateData(LPVOIDParameter);

intAPIENTRYWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPSTRlpCmdLine,
intnCmdShow)
{
WORDsockVersion;
//Usedtostoresocketversioninformation
WSADATAwsaData;//usedtostoreinfoaboutsocket
SOCKETs,client;//usedtocreateclientandserversocket
SOCKADDR_INsin;//usedtospecifyalocalorremoteendpointaddresstowhichtoconnectasocket
intrVal;//usedtostorereturnvalue

HANDLEhThread;
//Handletothread
DWORDThreadId;//usedtostorethethreadid

//Getthecurrentsocketversion
sockVersion=MAKEWORD(1,1);
//初始化Socket库
//TheWindowsSocketsWSAStartupfunctioninitiatesuseofWS2_32.DLLbyaprocess
WSAStartup(sockVersion,&wsaData);
//herewearecreatingthesocket
s=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
if(s==INVALID_SOCKET)
{
MessageBox(
0,"Invalidsocket","SocketError",MB_OK);
WSACleanup();
}

//fillinsockaddr_instruct
sin.sin_family=PF_INET;
sin.sin_port
=htons(8888);//监听端口为
sin.sin_addr.s_addr=INADDR_ANY;

//bindtothesocket
rVal=bind(s,(LPSOCKADDR)&sin,sizeof(sin));
if(rVal==SOCKET_ERROR)
{
MessageBox(
0,"FailedinbindAPI","BindError",MB_OK);
WSACleanup();
}


//Listentothedesireportonwhichclientsupposetoconnect
rVal=listen(s,2);//最大客户数目为
if(rVal==SOCKET_ERROR)
{
MessageBox(
0,"FailedinlistenAPI","ListenError",MB_OK);
WSACleanup();
}

//infinitelooptoservealltheclientswhichwantservice
while(1)
{
//Acceptthedatafromtheclient
client=accept(s,NULL,NULL);//接受来自客户端的连接

//Oncethenewclientcomeupcreateanewthreadtservetheclient
if(client)
{//创建线程去处理此请求,将此连接作为参数传给处理线程
hThread=CreateThread(NULL,
0,
ValidateData,
(LPVOID)client,
0,
&ThreadId);
}

else
return0;
}

return0;
}


DWORDWINAPIValidateData(LPVOIDParameter)
{
//Gettheinformationaboutcliententity
SOCKETclient=(SOCKET)Parameter;
intrVal;//Returnval
//数据缓冲区
charbuf[11];//usedtosendthevalidateddatatoclient

//Getthedataformclient
//接收数据
rVal=recv(client,buf,11,0);
//hereweareperformingsimplecheck,thedatacameformclient
//isvalidornot
//atthispointyoucancheckyourowndataalso,whichneedssomemodification
//回传数据给客户端
if(strcmp(buf,"DataOnSocket"))
{
//Sendbackthedatatotheclient
rVal=send(client,"YES",3,0);
}

else
{
//Sendbackthedatatotheclient
rVal=send(client,"NO",2,0);
}

return0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值