基于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,  00)) 
     {
        
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;
}
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值