当前位置: 首页 > news >正文

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

相关文章:

  • 转:在自己的工具条中使用ArcGIS Engine提供的命令和工具
  • 费劲千辛万苦终于找到了数据库!
  • 忽然之间
  • 在VS2008中使用WSE 3.0
  • ASP.NET中值类型与列类型不匹配的问题
  • 【PHP】日文全角转半角半角判断
  • 硬盘知识
  • 医药公司网站建设方案
  • 工作需要,了解了下HSRP.
  • 【转】华为Java笔试题
  • 2008年7月51CTO.com十大热点文章排行榜
  • Asp.net中防止用户多次登录的方法
  • WinInet学习笔记(一)WinInet简介
  • java解析芯片
  • Googlebot(谷歌机器人)深入了解
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • 5、React组件事件详解
  • ComponentOne 2017 V2版本正式发布
  • IndexedDB
  • jQuery(一)
  • Mysql数据库的条件查询语句
  • oldjun 检测网站的经验
  • Sequelize 中文文档 v4 - Getting started - 入门
  • vue-loader 源码解析系列之 selector
  • Zepto.js源码学习之二
  • 利用DataURL技术在网页上显示图片
  • 那些年我们用过的显示性能指标
  • 使用API自动生成工具优化前端工作流
  • 追踪解析 FutureTask 源码
  • ionic异常记录
  • zabbix3.2监控linux磁盘IO
  • 阿里云移动端播放器高级功能介绍
  • #NOIP 2014# day.1 T2 联合权值
  • $forceUpdate()函数
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (分布式缓存)Redis分片集群
  • (分布式缓存)Redis哨兵
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (一)WLAN定义和基本架构转
  • (转)h264中avc和flv数据的解析
  • (转)shell中括号的特殊用法 linux if多条件判断
  • (转)详解PHP处理密码的几种方式
  • ***利用Ms05002溢出找“肉鸡
  • ..回顾17,展望18
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Core 控制台程序读 appsettings.json 、注依赖、配日志、设 IOptions
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .netcore 获取appsettings
  • .NET开发不可不知、不可不用的辅助类(一)
  • .NET开发者必备的11款免费工具
  • ::什么意思
  • ??javascript里的变量问题
  • [.net 面向对象程序设计进阶] (19) 异步(Asynchronous) 使用异步创建快速响应和可伸缩性的应用程序...
  • [100天算法】-不同路径 III(day 73)