如何在不使用QTcpSockets的情况下创建插槽并将其连接到TCP recv()

how to create and connect slot in Qt to TCP recv() without using QTcpSockets?

本文关键字:连接 TCP recv 插槽 创建 情况下 QTcpSockets      更新时间:2023-10-16

我想在Qt中创建一个插槽,或者在C++TCP中的recv()函数中创建一个类似的东西,这样当套接字接收到数据时它会自动调用该插槽,我可以通过使用QTcpSockets来完成,但由于某些限制,我无法使用它们。

请引导我朝着正确的方向前进。

啧��

    ifndef TCP_H
    #define TCP_H
    #pragma once
    #include <WinSock2.h>
    #include <WS2tcpip.h>
    #include <iostream>
    #include "config.h"
    #include "tcp_packets.h"
    #include "change_ending.h"
    #include "md5.h"
    #pragma comment(lib, "Ws2_32.lib")
    class CTcpClient
    {
    private:
    char* szServerName;
    char*   Port;
    SOCKET ConnectSocket;
    md5checksum Md5Var;
    public:
        int Size;
        bool Send(char* szMsg,int len);
        CTcpClient(char* servername,char* port)
        {
            Port=port;
            szServerName = servername;
            ConnectSocket = INVALID_SOCKET;
            Size=0;

        }
        bool Start();
        void Stop();
        // Free the resouces


        // Receive message from server
         char recvbuf[DEFAULT_BUFFER_PKT_LENGTH];
        void Recv();

    };

TCP.cpp

    #endif // TCP_H
tcp.cpp
#include "tcp.h"
#include "config.h"
bool CTcpClient::Start() {
        WSADATA wsaData;
        // Initialize Winsock
        int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
        if(iResult != 0)
        {
            printf("WSAStartup failed: %dn", iResult);
            return false;
        }
        struct addrinfo *result = NULL,
                        *ptr = NULL,
                        hints;
        ZeroMemory(&hints, sizeof(hints));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        //hints.ai_protocol = SOL_SOCKET;
        //Resolve the server address and port
        iResult = getaddrinfo(szServerName,Port, &hints, &result);
        if (iResult != 0)
        {
            printf("getaddrinfo failed: %dn", iResult);
            WSACleanup();
            return false;
        }
        ptr = result;
        // Create a SOCKET for connecting to server
        ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);

        if (ConnectSocket == INVALID_SOCKET)
        {
            printf("Error at socket(): %dn", WSAGetLastError());
            freeaddrinfo(result);
            WSACleanup();
            return false;
        }
        // Connect to server
        iResult = connect(ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
        if (iResult == SOCKET_ERROR)
        {
            closesocket(ConnectSocket);
            ConnectSocket = INVALID_SOCKET;
        }
        freeaddrinfo(result);
        if (ConnectSocket == INVALID_SOCKET)
        {
            printf("Unable to connect to server!n");
            WSACleanup();
            return false;
        }
        return true;
    }
void CTcpClient::Stop() {
        int iResult = shutdown(ConnectSocket, SD_SEND);
        if (iResult == SOCKET_ERROR)
        {
            printf("shutdown failed: %dn", WSAGetLastError());
        }
        closesocket(ConnectSocket);
        WSACleanup();
    }
bool CTcpClient::Send(char* szMsg,int len)
    {
        int iResult = send(ConnectSocket, szMsg, len, 0);
        if (iResult == SOCKET_ERROR)
        {
            printf("send failed: %dn", WSAGetLastError());
            Stop();
            return false;
        }
        return true;
    }
void CTcpClient::Recv()
    {

        int iResult = recv(ConnectSocket, recvbuf, DEFAULT_REC_BUFFER_PKT_LENGTH, 0);
        Size=iResult;
        if (iResult > 0)
        {
            char msg[DEFAULT_REC_BUFFER_PKT_LENGTH];
            memset(&msg, 0, sizeof(msg));
            strncpy(msg, recvbuf, iResult);
            printf("Received: %sn", msg);

        }

        //return false;
    }

如果可以,你可以为 Recv() 函数创建单独的线程,并给它回调函数作为参数。然后在每次从套接字获取数据时在单独的线程调用回调函数中。

void callback(char *data){
     printf("Received: %srn", data);
}
void* thread_function(void *input){
     void (*callb)(char*) = (void (*)(char*))input;
     int recieve;
     while(1){
          receive = recv();
          if(receive > 0)
               callb();
     }
return NULL;
}
int main(){
pthread_t thread;
pthread_create(thread, NULL, thread_function, &callback);
/* do some stuff */
pthread_join(thread);
return 0;
}

像这样的东西。缺少很多变量和参数,但它显示了主要思想。