基于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;
}
//
#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;
}
//
#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。
posted on 2008-07-14 22:38 Phinecos(洞庭散人) 阅读(1346) 评论(2) 编辑 收藏 举报