基于Win32的多线程客户/服务器通信
客户端:
// Client.cpp : Defines the entry point for the application.
//

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

#pragma warning(disable:4700)

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text

// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;

// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_CLIENT, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);

// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}

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

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

return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

WORD version; //used to store the socket version
WSADATA wsaData; //used to store info about socket
SOCKET theSocket; //used to create client socket
SOCKADDR_IN serverInfo; //used to specify a local or remote endpoint address to which to connect a socket
int rVal; //used to store return value
LPHOSTENT hostEntry; //Windows Sockets allocates this structure
char *buf = "Data On Socket"; //Data to be send on socket

char data[5];
switch (message)
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
case IDM_COMMUNICATE:
//get the version of socket
version = MAKEWORD(1,1);
//The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process
rVal = WSAStartup(version,(LPWSADATA)&wsaData);
//store information about the server
//Here we are suppose to pass the server information to the client,
//so that the client knows where is the server
//I am using the machine name on wich my server.exe is running
hostEntry = gethostbyname("seclore3");
if(!hostEntry)
{
MessageBox(hWnd,"Failed in gethostbyname API","Gethostbyname Error",MB_OK);
WSACleanup();
break;
}
//here we are creating the socket
theSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(theSocket == SOCKET_ERROR)
{
MessageBox(hWnd,"Failed in socket API","Socket Error",MB_OK);
}
//Fill in the sockaddr_in struct
serverInfo.sin_family = PF_INET;
serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
serverInfo.sin_port = htons(8888);
//Connect to the socket we just created
rVal=connect(theSocket,(LPSOCKADDR)&serverInfo, sizeof(serverInfo));
if(rVal==SOCKET_ERROR)
{
MessageBox(hWnd,"Failed in connect API","Connect Error",MB_OK);
break;
}
//Send the data to the server
rVal = send(theSocket, buf, strlen(buf), 0);
if(rVal == SOCKET_ERROR)
{
MessageBox(hWnd,"Failed send","Send Error",MB_OK);
}
//Get/Recieve the data sent by the server
rVal = recv(theSocket,data,5,0);
if(rVal)
{
MessageBox(hWnd,data,"Data from server",MB_OK);
}
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here
RECT rt;
GetClientRect(hWnd, &rt);
DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
//Close the socket
closesocket(theSocket);
//The WSACleanup function initiates no action
WSACleanup();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Server.cpp : Defines the entry point for the application.
//

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

//function declaration
DWORD WINAPI ValidateData(LPVOID Parameter);

int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WORD sockVersion; //Used to store socket version information
WSADATA wsaData; //used to store info about socket
SOCKET s,client; //used to create client and server socket
SOCKADDR_IN sin; //used to specify a local or remote endpoint address to which to connect a socket
int rVal; //used to store return value

HANDLE hThread; //Handle to thread
DWORD ThreadId; //used to store the thread id

//Get the current socket version
sockVersion = MAKEWORD(1,1);
//初始化Socket库
//The Windows Sockets WSAStartup function initiates use of WS2_32.DLL by a process
WSAStartup(sockVersion, &wsaData);
//here we are creating the socket
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET)
{
MessageBox(0,"Invalid socket","Socket Error",MB_OK);
WSACleanup();
}
//fill in sockaddr_in struct
sin.sin_family = PF_INET;
sin.sin_port = htons(8888);//监听端口为
sin.sin_addr.s_addr = INADDR_ANY;

//bind to the socket
rVal = bind(s, (LPSOCKADDR)&sin, sizeof(sin));
if(rVal == SOCKET_ERROR)
{
MessageBox(0,"Failed in bind API","Bind Error",MB_OK);
WSACleanup();
}

//Listen to the desire port on which client suppose to connect
rVal = listen(s, 2);//最大客户数目为
if(rVal == SOCKET_ERROR)
{
MessageBox(0,"Failed in listen API","Listen Error",MB_OK);
WSACleanup();
}
//infinite loop to serve all the clients which want service
while(1)
{
//Accept the data from the client
client = accept(s, NULL, NULL);//接受来自客户端的连接

//Once the new client come up create a new thread t serve the client
if(client)
{//创建线程去处理此请求,将此连接作为参数传给处理线程
hThread = CreateThread(NULL,
0,
ValidateData,
(LPVOID)client,
0,
&ThreadId);
}
else
return 0;
}
return 0;
}

DWORD WINAPI ValidateData(LPVOID Parameter)
{
//Get the information about client entity
SOCKET client = (SOCKET)Parameter;
int rVal; //Return val
//数据缓冲区
char buf[11]; //used to send the validated data to client

//Get the data form client
//接收数据
rVal = recv(client,buf,11,0);
//here we are performing simple check, the data came form client
//is valid or not
//at this point you can check your own data also, which needs some modification
//回传数据给客户端
if(strcmp(buf,"Data On Socket"))
{
//Send back the data to the client
rVal = send(client,"YES",3,0);
}
else
{
//Send back the data to the client
rVal = send(client,"NO",2,0);
}
return 0;
}
































































































































































服务器端:










































































































作者:洞庭散人
出处:http://phinecos.cnblogs.com/
本博客遵从Creative Commons Attribution 3.0 License,若用于非商业目的,您可以自由转载,但请保留原作者信息和文章链接URL。
分类:
C/C++/VC++
posted on 2008-07-14 22:38 Phinecos(洞庭散人) 阅读(1347) 评论(2) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述