-1

我从主线程创建一个线程

void xui(PLDR_DATA_TABLE_ENTRY ModuleHandle){  
ExCreateThread(&moduleHandle, 0, &threadId, ConnectSock , (LPTHREAD_START_ROUTINE)ConnectSock, NULL, 0x02);
}

调用的线程

DWORD WINAPI ConnectSock() {
SOCKET Sock = NetDll_socket(XNCALLER_SYSAPP, AF_INET, SOCK_STREAM, IPPROTO_TCP);
    BYTE IPAddress[0x4] =  { 34, 231, 248, 251 };
    WORD Port = 6667;
    DWORD SocketError;
    XNetStartupParams xnsp;
    WSADATA WsaData;
    BOOL SockOpt = TRUE;
    DWORD sendRecvSize = 1024;
    sockaddr_in httpServerAdd;
    httpServerAdd.sin_addr.S_un.S_addr = *(PDWORD)IPAddress;
    //httpServerAdd.sin_addr.s_addr = inet_addr("tha-row.net");
    httpServerAdd.sin_port = htons(Port);
    httpServerAdd.sin_family = AF_INET;
    ZeroMemory(&xnsp, sizeof(xnsp));

    // Configure our xnsp variable
    xnsp.cfgSizeOfStruct = sizeof(XNetStartupParams);
    xnsp.cfgFlags = XNET_STARTUP_BYPASS_SECURITY;
    // Safely startup XNet
    if ((SocketError = NetDll_XNetStartup(XNCALLER_SYSAPP, &xnsp)) != S_OK) {

    }

    // Safely startup WSA
    if ((SocketError = NetDll_WSAStartupEx(XNCALLER_SYSAPP, MAKEWORD(2, 2), &WsaData, 2)) != S_OK) {

    }

    // Safely create socket
    //Sock = NetDll_socket(XNCALLER_SYSAPP, AF_INET, SOCK_STREAM, IPPROTO_TCP);
    //Sock = socket(AF_INET, SOCK_STREAM, 0);
    // Disable network encryption
    if (NetDll_setsockopt(XNCALLER_SYSAPP, Sock, SOL_SOCKET, 0x5801, (PCSTR)&SockOpt, 4) != S_OK) {

    }

    // Configure socket send/recv size
    NetDll_setsockopt(XNCALLER_SYSAPP, Sock, SOL_SOCKET, SO_SNDBUF, (PCSTR)&sendRecvSize, 4);
    NetDll_setsockopt(XNCALLER_SYSAPP, Sock, SOL_SOCKET, SO_RCVBUF, (PCSTR)&sendRecvSize, 4);

    // Create connection timeout
    struct timeval tv;
    tv.tv_sec = 15;
    tv.tv_usec = 0;
    setsockopt(Sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(struct timeval));

    if (NetDll_connect(XNCALLER_SYSAPP, Sock, (struct sockaddr*)&httpServerAdd, sizeof(httpServerAdd)) == SOCKET_ERROR) {
        std::string wsacon("subtitle_add \"fai!");
        wsacon += "\" 3";
        const char* Nwsacon = wsacon.c_str();
        ConsoleCommand2(Nwsacon);
    }
    int ReadBytes = 0;
    ofstream ircdata;
    char buff[1024];
    while (true)
    {
        ZeroMemory(buff, 1024);

        int bytesReceived = NetDll_recv(XNCALLER_SYSAPP,Params->sock, buff, 1024, 0);
        if (bytesReceived == SOCKET_ERROR)
        {

        }
        if (bytesReceived > 0) {
        }
    }
    NetDll_closesocket(XNCALLER_SYSAPP, Sock);
}

我如何从新创建的线程外部访问“Sock”并发送消息,例如

string string2send = "string to send\n";
                            NetDll_send(XNCALLER_SYSAPP, Sock,string2send.c_str(), string2send.length(), 0);

请注意,这不是套接字的全部代码,我尽可能地缩短了它以表达我的观点..

我只想从另一个线程发送到套接字

如果我有

SOCKET Sock = NetDll_socket(XNCALLER_SYSAPP, AF_INET, SOCK_STREAM, IPPROTO_TCP);

作为全局变量 Sock 在线程外仍然等于 0

4

2 回答 2

0

所以感谢@Remy 和@pm100 这对我有用

void Player::ExternalMsg(){
string Z = "IRCX\r\n";
    NetDll_send(XNCALLER_SYSAPP, Sock2, Z.c_str(), Z.length(), 0);
}
void SendSockInfo(SOCKET s) {
    Sock2 = s;
}

在我成功连接后

SendSockInfo(sock);
于 2022-02-16T22:39:23.980 回答
0

你有几个选择

  • 使 Sock 全球化
  • 在线程启动参数中传入一个 Sock 指针
  • 在将 Sock 作为参数传递的连接函数中调用某个方法并在该函数中启动发送线程,将 Sock 传递给它(如选项 2 中所示)

在前两种情况下,您需要一些同步原语才能在连接之前不使用 Socket。

顺便说一句,对于处理 TCP 连接的代码来说,这是一个不寻常的“形状”。通常一个线程处理一个连接

于 2022-02-16T21:45:54.037 回答