1

TCPのrecv()関数用にQtまたはC++で同様のものを作成したいので、ソケットがデータを受信するとスロットが自動的に呼び出されます.QTcpSocketsを使用してそれを行うことができますが、それらを使用することはできません.いくつかの制限があるため、現在、recv() 関数からデータを受信するためにタイマーを使用しています。

私を正しい方向に導いてください。

tcp.h

    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: %d\n", 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: %d\n", 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(): %d\n", 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: %d\n", 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: %d\n", 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: %s\n", msg);


        }


        //return false;
    }
4

1 に答える 1

1

可能であれば、Recv() 関数用に別のスレッドを作成し、コールバック関数をパラメーターとして渡すことができます。次に、ソケットからデータを取得するたびに、別のスレッドでコールバック関数を呼び出します。

void callback(char *data){
     printf("Received: %s\r\n", 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;
}

このようなもの。多くの変数と引数が欠落していますが、主なアイデアを示しています。

于 2013-09-17T14:16:06.290 に答える