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

复制代码



本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/07/14/1242960.html,如需转载请自行联系原作者
目录
相关文章
|
29天前
|
Java
Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
57 1
|
1月前
|
API Windows
揭秘网络通信的魔法:Win32多线程技术如何让服务器化身超级英雄,同时与成千上万客户端对话!
【8月更文挑战第16天】在网络编程中,客户/服务器模型让客户端向服务器发送请求并接收响应。Win32 API支持在Windows上构建此类应用。首先要初始化网络环境并通过`socket`函数创建套接字。服务器需绑定地址和端口,使用`bind`和`listen`函数准备接收连接。对每个客户端调用`accept`函数并在新线程中处理。客户端则通过`connect`建立连接,双方可通过`send`和`recv`交换数据。多线程提升服务器处理能力,确保高效响应。
35 6
|
1月前
|
网络协议 安全 Unix
6! 用Python脚本演示TCP 服务器与客户端通信过程!
6! 用Python脚本演示TCP 服务器与客户端通信过程!
|
19天前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
42 0
|
30天前
|
存储 安全 Java
【多线程面试题 七】、 说一说Java多线程之间的通信方式
Java多线程之间的通信方式主要有:使用Object类的wait()、notify()、notifyAll()方法进行线程间协调;使用Lock接口的Condition的await()、signal()、signalAll()方法实现更灵活的线程间协作;以及使用BlockingQueue作为线程安全的队列来实现生产者和消费者模型的线程通信。
|
1月前
|
C语言
【C语言】多线程服务器
【C语言】多线程服务器
16 0
|
10天前
|
Cloud Native Java 编译器
将基于x86架构平台的应用迁移到阿里云倚天实例云服务器参考
随着云计算技术的不断发展,云服务商们不断推出高性能、高可用的云服务器实例,以满足企业日益增长的计算需求。阿里云推出的倚天实例,凭借其基于ARM架构的倚天710处理器,提供了卓越的计算能力和能效比,特别适用于云原生、高性能计算等场景。然而,有的用户需要将传统基于x86平台的应用迁移到倚天实例上,本文将介绍如何将基于x86架构平台的应用迁移到阿里云倚天实例的服务器上,帮助开发者和企业用户顺利完成迁移工作,享受更高效、更经济的云服务。
将基于x86架构平台的应用迁移到阿里云倚天实例云服务器参考
|
8天前
|
编解码 前端开发 安全
通过阿里云的活动购买云服务器时如何选择实例、带宽、云盘
在我们选购阿里云服务器的过程中,不管是新用户还是老用户通常都是通过阿里云的活动去买了,一是价格更加实惠,二是活动中的云服务器配置比较丰富,足可以满足大部分用户的需求,但是面对琳琅满目的云服务器实例、带宽和云盘选项,如何选择更适合自己,成为许多用户比较关注的问题。本文将介绍如何在阿里云的活动中选择合适的云服务器实例、带宽和云盘,以供参考和选择。
通过阿里云的活动购买云服务器时如何选择实例、带宽、云盘
|
6天前
|
弹性计算 运维 安全
阿里云轻量应用服务器和经济型e实例区别及选择参考
目前在阿里云的活动中,轻量应用服务器2核2G3M带宽价格为82元1年,2核2G3M带宽的经济型e实例云服务器价格99元1年,对于云服务器配置和性能要求不是很高的阿里云用户来说,这两款服务器配置和价格都差不多,阿里云轻量应用服务器和ECS云服务器让用户二选一,很多用户不清楚如何选择,本文来说说轻量应用服务器和经济型e实例的区别及选择参考。
阿里云轻量应用服务器和经济型e实例区别及选择参考
|
7天前
|
机器学习/深度学习 存储 人工智能
阿里云GPU云服务器实例规格gn6v、gn7i、gn6i实例性能及区别和选择参考
阿里云的GPU云服务器产品线在深度学习、科学计算、图形渲染等多个领域展现出强大的计算能力和广泛的应用价值。本文将详细介绍阿里云GPU云服务器中的gn6v、gn7i、gn6i三个实例规格族的性能特点、区别及选择参考,帮助用户根据自身需求选择合适的GPU云服务器实例。
阿里云GPU云服务器实例规格gn6v、gn7i、gn6i实例性能及区别和选择参考

热门文章

最新文章