题记:
我下面的帖的代码是 服务器 端,下面称呼客户端为 客户 。
1。首先由客户 发"R_MNG_REQ"字符串,服务器若成功接收就回传 字符串"R_MNG_ACK OK"2。若 1。成功,则客户发字符串"R_LINK_REQ",服务器回传 字符串"R_LINK_REPORT\r\n"。3。若 1。成功,则客户每隔60秒给服务器发字符串"ACTIVE\r\n"。下面是我写的服务器代码,我专门起了一个线程来接收字符串"ACTIVE\r\n",但等了好长时间都没收到"ACTIVE\r\n",为什么?代码如下:#pragma comment (lib,"ws2_32.lib")
#include <Winsock2.h>
#include <stdio.h>#define TOA_COMMAND_START "R_MNG_REQ"
#define TOA_COMMAND_MNG_ACK_OK "R_MNG_ACK OK"
#define TOA_COMMAND_MNG_ACK_NG "R_MNG_ACK NG"
#define TOA_COMMAND_GET_STATUS "R_LINK_REQ"
#define TOA_LINK_REPORT             "R_LINK_REPORT\r\n"
#define TOA_COMMAND_ACTIVE "ACTIVE\r\n"DWORD WINAPI testActive(
LPVOID lpparameter
);void main()
{
// 加载套接字库
WORD wVersionRequested;
WSADATA wsaData;
int err;
char recvBuf[100] ;
memset(recvBuf,0,100); wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData);
if (err != 0) {
return;
} if (LOBYTE(wsaData.wVersion ) != 2 ||
HIBYTE(wsaData.wVersion ) != 2) 
{
WSACleanup( );
return; 
} // 创建用于监听的套接字
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5001); // 绑定套接字
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
// 将套接字设为监听模式,准备接收客户请求
listen(sockSrv, 5); SOCKADDR_IN service;
int len = sizeof(SOCKADDR); // 心跳指令
HANDLE hThread;
hThread = CreateThread(NULL, 0, testActive, NULL, 0, NULL);
CloseHandle(hThread); while(1)
{
// 等待客户请求到来 
SOCKET sockConn=accept(sockSrv, (SOCKADDR*)&service,&len); // 接收数据
recv(sockConn, recvBuf, 100, 0);
printf("%s", recvBuf);
// system("pause"); // 如果接收到 R_MNG_REQ 则返回一个 R_MNG_ACK OK
if(!memcmp(recvBuf,TOA_COMMAND_START,strlen(TOA_COMMAND_START)))
{
send(sockConn, TOA_COMMAND_MNG_ACK_OK, strlen(TOA_COMMAND_MNG_ACK_OK)+1, 0);
} // 接收数据
recv(sockConn, recvBuf, strlen(recvBuf), 0);
printf("%s", recvBuf); // 如果接收到 R_LINK_REQ 则返回一个 R_LINK_REPORT\r\n
if(!memcmp(recvBuf,TOA_COMMAND_GET_STATUS,strlen(TOA_COMMAND_GET_STATUS)))
{
send(sockConn, TOA_LINK_REPORT, strlen(TOA_LINK_REPORT)+1,0);
}

// 关闭套接字
// closesocket(sockConn);
}
}DWORD WINAPI testActive(
LPVOID lpparameter
)
{  
char recvBuf[100];
memset(recvBuf,0,100); printf("新线程\n"); // 创建用于监听ACTIVE命令的套接字
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(5001); // 绑定套接字
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); // 将套接字设为监听模式,准备接收客户请求
listen(sockSrv, 5); SOCKADDR_IN service;
int len = sizeof(SOCKADDR); while(1)
{
// 等待客户请求到来 
SOCKET sockConn=accept(sockSrv, (SOCKADDR*)&service,&len);
// 接收数据
recv(sockConn, recvBuf, 100, 0);
if(!memcmp(recvBuf,TOA_COMMAND_ACTIVE,strlen(TOA_COMMAND_ACTIVE)))
{
printf("%s", recvBuf);
}
} return 0;
}

解决方案 »

  1.   

    那个现成为什么还要重新监听,据你的介绍应该是把主线程的socket句柄传进去吧
      

  2.   

    你服务器端和客户端对应着Debug下调试一下,还有判断一下winsock API函数的返回值,不都不判断是否成功或者失败的?
      

  3.   

    还有你的线程里在干吗,主线程里listen-accept,子线程里又listen-accept()?这个是在干吗?
      

  4.   

    主进程与线程中的那两个套节字没有关系,除非你的客户端用的是两个socket对服务器的不同端口进行连接
      

  5.   

    你要不就是在主线程的accept中调用hThread = CreateThread(NULL, 0, testActive, (LPOID)sockConn, 0, NULL);
    ,传入连接的套接字..
    如果不是多客户端程序同时连接服务器的话,直接把Active中判断是Active的代码放到主线程的死循环中
      

  6.   

    您说的太对了,还有楼上的各位,谢谢,我第一次用socket编程,见笑了。引:你要不就是在主线程的accept中调用hThread = CreateThread(NULL, 0, testActive, (LPOID)sockConn, 0, NULL);可我的sockConn是在while(1)死循环里产生的啊,难道我的线程要在死循环里不停地创建。如果按您说的 传入套接字,hThread = CreateThread(NULL, 0, testActive, (LPVOID)&sockSrv, 0, NULL); 但此时我在线程里 recv(sockConn, recvBuf, 100, 0); 这其中的sockConn改怎么得到啊?因为主线程里要进入 死循环 后才能得到 sockconn啊
      

  7.   

    引:如果不是多客户端程序同时连接服务器的话,直接把Active中判断是Active的代码放到主线程的死循环中我把判断Active的代码放在主线程中,也接收不到啊,之前我试过了
      

  8.   

    要循环接收啊,你找个socket小例子看看吧
      

  9.   

    部长,我问下您 加载套接字库的动作在 主线程和线程中 只要初始化一次就可以了吧?在线程中就不需要再次加载和初始化了吧?
    // 加载套接字库
        WORD wVersionRequested;
        WSADATA wsaData;
        int err;
        char recvBuf[100] ;
        memset(recvBuf,0,100);    wVersionRequested = MAKEWORD(2, 2);    err = WSAStartup(wVersionRequested, &wsaData);
        if (err != 0) {
            return;
        }    if (LOBYTE(wsaData.wVersion ) != 2 ||
            HIBYTE(wsaData.wVersion ) != 2) 
        {
                WSACleanup( );
                return; 
        }
      

  10.   

    现在可以接受到了,谢谢各位以下是修改后的代码,对比一下,哪位能解释一下原因吗?代码如下:
    #pragma comment (lib,"ws2_32.lib")
    #include <Winsock2.h>
    #include <stdio.h>#define TOA_COMMAND_START "R_MNG_REQ"
    #define TOA_COMMAND_MNG_ACK_OK "R_MNG_ACK OK"
    #define TOA_COMMAND_MNG_ACK_NG "R_MNG_ACK NG"
    #define TOA_COMMAND_GET_STATUS "R_LINK_REQ"
    #define TOA_LINK_REPORT             "R_LINK_REPORT\r\n"
    #define TOA_COMMAND_ACTIVE "ACTIVE\r\n"DWORD WINAPI testActive(
    LPVOID lpparameter
    );void main()
    {
    // 加载套接字库
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    char recvBuf[100] ;
    memset(recvBuf,0,100); wVersionRequested = MAKEWORD(2, 2); err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0) {
    return;
    } if (LOBYTE(wsaData.wVersion ) != 2 ||
    HIBYTE(wsaData.wVersion ) != 2) 
    {
    WSACleanup( );
    return; 
    } // 创建用于监听的套接字
    SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(5001); // 绑定套接字
    bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
    // 将套接字设为监听模式,准备接收客户请求
    listen(sockSrv, 5); SOCKADDR_IN service;
    int len = sizeof(SOCKADDR); // 等待客户请求到来 
    SOCKET sockConn=accept(sockSrv, (SOCKADDR*)&service,&len); // 心跳指令
    HANDLE hThread;
    hThread = CreateThread(NULL, 0, testActive,(LPVOID) sockSrv, 0, NULL);
    CloseHandle(hThread); while(1)
    {
    // 接收数据
    recv(sockConn, recvBuf, 100, 0);
    printf("%s", recvBuf);
    // system("pause"); // 如果接收到 R_MNG_REQ 则返回一个 R_MNG_ACK OK
    if(!memcmp(recvBuf,TOA_COMMAND_START,strlen(TOA_COMMAND_START)))
    {
    send(sockConn, TOA_COMMAND_MNG_ACK_OK, strlen(TOA_COMMAND_MNG_ACK_OK)+1, 0);
    } // 接收数据
    recv(sockConn, recvBuf, strlen(recvBuf), 0);
    printf("%s", recvBuf); // 如果接收到 R_LINK_REQ 则返回一个 R_LINK_REPORT\r\n
    if(!memcmp(recvBuf,TOA_COMMAND_GET_STATUS,strlen(TOA_COMMAND_GET_STATUS)))
    {
    send(sockConn, TOA_LINK_REPORT, strlen(TOA_LINK_REPORT)+1,0);
    }

    recv(sockConn, recvBuf, 100, 0);
    if(!memcmp(recvBuf,TOA_COMMAND_ACTIVE,strlen(TOA_COMMAND_ACTIVE)))
    {
    printf("%s", recvBuf);
    } // 关闭套接字
    // closesocket(sockConn);
    }
    }DWORD WINAPI testActive(
    LPVOID lpparameter
    )
    {  
    char recvBuf[100];
    memset(recvBuf,0,100);
    SOCKET sockConn=(SOCKET)lpparameter; while(1)
    {
    recv(sockConn, recvBuf, 100, 0);
    if(!memcmp(recvBuf,TOA_COMMAND_ACTIVE,strlen(TOA_COMMAND_ACTIVE)))
    {
    printf("%s", recvBuf);
    }
    } return 0;
    }
      

  11.   

    上面都讲到了,原因是你子线程里面重新创建的socket绑定无效,也就是句柄是无效的,即接收不到任何数据咯。但是你放在主线程之后就可以收到数据了