天天看点

基于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);

        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);

            //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);

        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);

    case WM_DESTROY:

        //Close the socket

        closesocket(theSocket);

        //The WSACleanup function initiates no action 

        WSACleanup();

        PostQuitMessage(0);

    default:

        return DefWindowProc(hWnd, message, wParam, lParam);

    return 0;

服务器端:

// Server.cpp : Defines the entry point for the application.

//function declaration

DWORD WINAPI ValidateData(LPVOID Parameter);

    WORD sockVersion;    //Used to store socket version information

    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

    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);

    //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);

    //Listen to the desire port on which client suppose to connect

    rVal = listen(s, 2);//最大客户数目为

        MessageBox(0,"Failed in listen API","Listen Error",MB_OK);

    //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,

                &ThreadId);

        else

            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

        rVal = send(client,"NO",2,0);

本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/07/14/1242960.html,如需转载请自行联系原作者

继续阅读