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

标签 c++ windows sockets tcp winsock

我想使用 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

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

希望对您有所帮助。

Mmarss

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

相关文章:

php - 在 PHP exec 中重定向 STDERR

c - 是否可以使用 epoll,以及将 epoll 与 Netmap 一起使用来加速是否有意义?

c++ - 使用正则表达式搜索注释掉的代码

c++ - 错误 LNK2019 : unresolved external symbol for class unordered_map

c++ - 直方图均衡不适用于彩色图像 - OpenCV

java - 完全合格的路径Vs。规范路径

c# - 以编程方式验证 Windows 密码策略?

c++ - 如何访问传递给 MEX 函数的矩阵成员?

java - 服务器和客户端之间的多个套接字

c++ - 在 C++ 中监听后如何从同一端口发送数据?