草庐IT

c++ - 使用 TCP 套接字 (WIN32 API) 创建的两个窗口之间的通信

coder 2023-09-19 原文

我想使用 WINAPI 创建两个窗口,然后我想使用 TCP scokets 在它们之间进行通信。 到目前为止,我已经成功地创建了两个窗口并且也成功地打开了套接字。但是两个窗口将如何使用此套接字进行通信?这是我到目前为止编写的代码:

另一个问题是代码只将数据从服务器发送到客户端一次。此外,除非数据从服务器发送到客户端一次,否则不会处理其他 Windows 消息:( 有人帮帮我吗?在此处输入代码服务器窗口:

// Program Name: server_window
// ===============================
// Author Name: Ayesha Hassan
// ===============================
// The Program creates a Listening Socket and waits for the client.
// As soon as a Client is connected to this Server's Listening Socket, a Window is launched.      
// When the user Clicks on this window using Mouse, a Message is sent to the Client over the Connected Socket. 

#include <windows.h>
#include <iostream.h>
#include "stdafx.h"
#include <winsock2.h>
#include <stdio.h>
#include <tchar.h>
#include "resource.h"
#pragma comment(lib,"ws2_32.lib")

SOCKET AH_GlbSocket;

const char AH_GlbClassName[] = "myWindClass";   ///Window Class Name
HWND AH_Glb_hwnd;   //Header to Window

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, 
            WPARAM wParam, LPARAM lParam)
{
char message[]="Mouse Clicked On SERVER Window";
HDC hdc;

//Gets Handle for the Window 
hdc=GetDC(hwnd);

char buffer[1000];
memset(buffer,0,999);

   switch(msg)
      {

      case WM_LBUTTONDOWN:
      //Sends Text to be displayed oon Client Window
         send(AH_GlbSocket, message, strlen(message), 0);
         break;

      case WM_CREATE:
          {
             WSADATA WsaDat;
             if(WSAStartup(MAKEWORD(2,2), &WsaDat)!=0)
                {
                   //printf("WSA Initialization failed!\r\n");
                   WSACleanup();
                   system("PAUSE");
                   return 0;
                }

                AH_GlbSocket=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
                if(AH_GlbSocket == INVALID_SOCKET)
                   {
                      //printf("AH_GlbSocket creation failed.\r\n");
                      WSACleanup();
                      system("PAUSE");
                      return 0;
                   }
                //else
                   //printf("Socket created.\n");

                SOCKADDR_IN serverInf;
                serverInf.sin_family = AF_INET;
                serverInf.sin_addr.s_addr = INADDR_ANY;
                serverInf.sin_port = htons(8888);

                if(bind(AH_GlbSocket,(SOCKADDR*)(&serverInf), sizeof(serverInf)) == SOCKET_ERROR)
                   {
                      //printf("Unable to bind AH_GlbSocket!\r\n");
                      WSACleanup();
                      system("PAUSE");
                      return 0;
                   }

                listen(AH_GlbSocket, 1);
                SOCKET TempSock = SOCKET_ERROR;

                while(TempSock == SOCKET_ERROR)
                {
                   //printf("Waiting for incoming connections...\n\n");
                  TempSock = accept(AH_GlbSocket, NULL, NULL);
                }
                AH_GlbSocket = TempSock;


         }
         break;
      case WM_CLOSE:
         DestroyWindow(hwnd);
         break;

      case WM_DESTROY:
         PostQuitMessage(0);
         break;

      default:
         return DefWindowProc(hwnd, msg, wParam, lParam);
      }
    return 0;
}

int WINAPI WinMain(  HINSTANCE hInstance, 
  HINSTANCE hPrevInstance, 
  LPSTR lpCmdLine, 
  int nShowCmd )
{


   WNDCLASSEX wc;
   MSG Msg;

   //Step 1: Registering the Window Class
   wc.cbSize        = sizeof(WNDCLASSEX);
   wc.style         = 0;
   wc.lpfnWndProc   = WndProc;
   wc.cbClsExtra    = 0;
   wc.cbWndExtra    = 0;
   wc.hInstance     = NULL;
   wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
   wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
   wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
   wc.lpszMenuName  = NULL;
   wc.lpszClassName = AH_GlbClassName;
   wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);  
   //wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MYMENU);
   //wc.hIcon  = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
   //wc.hIconSm  = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 26, 26, 0);

   if(!RegisterClassEx(&wc))
   {
      MessageBox(NULL, "Window Registration Failed!", "Error!",
                  MB_ICONEXCLAMATION | MB_OK);
      return 0;
   }

   // Step 2: Creating Window1
   AH_Glb_hwnd = CreateWindowEx( WS_EX_CLIENTEDGE,
                                 AH_GlbClassName,
                                 "I am SERVER Window",
                                 WS_OVERLAPPEDWINDOW,
                                10,30, 540, 220,
                                 NULL, NULL, NULL, NULL);
   if(AH_Glb_hwnd == NULL)
   {
      MessageBox(NULL, "Window Creation Failed!", "Error!",
                 MB_ICONEXCLAMATION | MB_OK);
      return 0;
   }

   ShowWindow(AH_Glb_hwnd,SW_SHOWDEFAULT);
   UpdateWindow(AH_Glb_hwnd);

   // Step 3: The Message Loop
   while(GetMessage(&Msg, NULL, 0, 0) > 0)
   {
      TranslateMessage(&Msg);
      DispatchMessage(&Msg);
   }
   return Msg.wParam; 


}


***CLIENT WINDOW:***
#include <windows.h>
#include "stdafx.h"
//#include <iostream.h>
#include <winsock2.h>
#include <stdio.h>
#include "resource.h"
#pragma comment(lib,"ws2_32.lib")

SOCKET AH_Glb_Socket;

const char AH_Glb_ClassName[] = "myWindClass";
HWND AH_Glb_hwnd;


// Step 4: the Window Procedure
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{


    switch(msg)
    {

        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);

    }
    return 0;
}



int WINAPI WinMain(  HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
    // Initialise Winsock
    WSADATA WsaDat;  

    if(WSAStartup(MAKEWORD(2,2),&WsaDat)!=0)
    {
        printf("Winsock error - Winsock initialization failed");
        WSACleanup();
        system("PAUSE");
        return 0;
    }
    char* buff="CLIENT says: I am Going to connect to the server now\n\n";
    printf(buff,sizeof(buff));
    // Create our socket
    SOCKET Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(Socket==INVALID_SOCKET)
    {
        printf("Winsock error - Socket creation Failed!\r\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    // Resolve IP address for hostname
    struct hostent *host;
    if((host=gethostbyname("localhost"))==NULL)
    {
        printf("Failed to resolve hostname.\r\n");
        WSACleanup();
        system("PAUSE");
        return 0;
    }

    // Setup our socket address structure
    SOCKADDR_IN SockAddr;
    SockAddr.sin_port=htons(8888);
    SockAddr.sin_family=AF_INET;
    SockAddr.sin_addr.s_addr=*((unsigned long*)host->h_addr);

    // Attempt to connect to server
    if(connect(Socket,(SOCKADDR*)(&SockAddr),sizeof(SockAddr))!=0)
    {
        printf("Failed to establish connection with server\r\n");
        WSACleanup();
        //system("PAUSE");
        //return 0;
    }

    WNDCLASSEX wc;

    MSG Msg;

    //Step 1: Registering the Window Class
    wc.cbSize        = sizeof(WNDCLASSEX);
    wc.style         = 0;
    wc.lpfnWndProc   = WndProc;
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = NULL;
    wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
    wc.lpszMenuName  = NULL;
    wc.lpszClassName = AH_Glb_ClassName;
    wc.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    //wc.lpszMenuName  = MAKEINTRESOURCE(IDR_MYMENU);
    //wc.hIcon  = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
    //wc.hIconSm  = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 26, 26, 0);

    if(!RegisterClassEx(&wc))
    {
        MessageBox(NULL, "Window Registration Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    // Step 2: Creating Window1
    AH_Glb_hwnd = CreateWindowEx(
        WS_EX_CLIENTEDGE,
        AH_Glb_ClassName,
        "I am CLIENT Window",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, 440, 120,
        NULL, NULL, NULL, NULL);

    if(AH_Glb_hwnd == NULL)
    {
        MessageBox(NULL, "Window Creation Failed!", "Error!",
            MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }

    ShowWindow(AH_Glb_hwnd,SW_SHOWDEFAULT);
    UpdateWindow(AH_Glb_hwnd);

    char buffer[1000];
    memset(buffer,0,999);

        recv(Socket,buffer,1000,0);
        printf(buffer,sizeof(buffer));
        TextOut(GetDC(AH_Glb_hwnd),5,5,buffer,sizeof(buffer));


    // Step 3: The Message Loop
    while(GetMessage(&Msg, NULL, 0, 0) > 0)
    {   
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;


}

最佳答案

尝试使用 WSAAsyncSelect 建立基于消息的连接;这样您就可以在程序运行时继续发送/接收消息。

有关 WSAAsyncSelect 函数的更多信息,请参见此处: http://msdn.microsoft.com/en-us/library/windows/desktop/ms741540%28v=vs.85%29.aspx

在 codeproject.com 上还有一个关于使用 WIN32 API + winsock 的优秀教程:http://www.codeproject.com/Articles/13071/Programming-Windows-TCP-Sockets-in-C-for-the-Begin

如果您遵循教程,包括注册窗口消息,您应该能够多次从服务器向客户端发送数据,反之亦然,直到套接字关闭。

希望对您有所帮助。

妈妈

关于c++ - 使用 TCP 套接字 (WIN32 API) 创建的两个窗口之间的通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15170898/

有关c++ - 使用 TCP 套接字 (WIN32 API) 创建的两个窗口之间的通信的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  10. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

随机推荐