我用socket2的API写了服务器和客户端,客户端连两个时,前面一个就不能正常工作(好像是被阻塞了)
VC代码见http://www4.7show.net/luck8888/sck
麻烦加上“.rar”--------------------------
特向高手请教,接受socket,拒绝MFC
--------------------------附:client端代码
#include <stdio.h>
#include <winsock2.h>void main()
{
WSADATA wsaData;
SOCKET clientSocket;
int err;

//WSAStartup
if(WSAStartup(0x0202, &wsaData)!=0)
{
err=WSAGetLastError();
printf("无法使用Socket库,错误代码:%d\n",err);
return;
} //socket
  clientSocket = socket(AF_INET, SOCK_STREAM, 0);
if(clientSocket == SOCKET_ERROR)
{
printf("建立socket失败\n");
return;
} struct sockaddr_in serverAddr; //连接服务器
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //htonl(INADDR_ANY);
serverAddr.sin_port=htons(8001);
memset(serverAddr.sin_zero,0,8); clientSocket = socket(AF_INET, SOCK_STREAM, 0); if(connect(clientSocket, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == SOCKET_ERROR) 
{
printf("connect错误,错误代码:%d",WSAGetLastError());
closesocket(clientSocket);
WSACleanup();
exit(1);
}
char msg[256];
int bQuit=0;
int nRet;

while(!bQuit)
{
gets(msg);
if(strcmp(msg,"quit")==0) bQuit=1; //发送数据
nRet = send(clientSocket, msg, strlen(msg), 0);
if(nRet == SOCKET_ERROR)
{
printf("send错误,错误代码:%d",WSAGetLastError());
continue;
} //接收数据
char buf[256]; ///////////////////////////////////// printf("准备接收...\n");

nRet = recv(clientSocket, buf, 255, 0);
if(nRet > 0)
{
buf[nRet] = 0;
printf("\n收到的回复为:%s",buf);
}
else
{
printf("\nrecv error: %d\n", nRet);
} } shutdown(clientSocket, SD_RECEIVE);
closesocket(clientSocket);
WSACleanup();}

解决方案 »

  1.   

    你的服务端是否为每一个客户端请求建立了一个通信SOCKET?
      

  2.   

    服务器端:
    ----------------------------------------
        sClient = accept(listenSocket, (struct sockaddr *)&clientAddr, &nAddrLen); if(sClient == SOCKET_ERROR)
    {
    err = WSAGetLastError();
    printf("\naccept错误,错误代码:%d\n",err);
    return;
    }
    else
    {
    printf("接受来自%s的连接请求\n",inet_ntoa(clientAddr.sin_addr)); //建立一个线程处理请求
    static PARAMS params;

    //线程处理函数的参数
    params.IP = clientAddr.sin_addr;
    params.port = clientAddr.sin_port;
    params.s = sClient; HANDLE hThread=(void *)_beginthread(ThreadFunc,0,(void *)&params);
    CloseHandle(hThread);
    --------------------------------------
    这是线程处理函数
    --------------------------------------
    void ThreadFunc(void *pvoid)
    {
    PARAMS *pParams;  pParams = (PARAMS *) pvoid ; printf("连接上%s:%u socket=0x%X\n", inet_ntoa(pParams->IP), ntohs(pParams->port), pParams->s);
    int nRet;
    char buf[256]; while(1)
    {
    printf("socket=0x%X\n", pParams->s); //在接收数据前,可以另开一个线程来处理超时
    nRet = recv(pParams->s, buf, 255, 0); if(nRet > 0)
    {
    buf[nRet] = 0;
    printf("收到的信息为:%s",buf);
    }
    else
    {
    printf("recv error: %d\n", nRet);
    break;
    }
    //printf("\n接收完毕!\n");
    //收到停止服务命令
    if(strcmp(buf,"stop")==0)
    {
    closesocket(pParams->s);
    closesocket(listenSocket);
    WSACleanup();
    printf("server stopped by admin.\n");
    _endthread();
    }
    //发回到客户端
    Sleep(20);
    printf("\n开始回复客户端...");
    strcpy(buf,"消息已收到\n");
    nRet = send(pParams->s,buf,strlen(buf),0); if(nRet > 0)
    {
    buf[nRet] = 0;
    printf("回复成功\n---------------------------\n");
    }
    else
    {
    printf("\nsend error: %d\n", nRet);
    break;
    } }
    closesocket(pParams->s);
    printf("断开%s:%u socket=0x%X\n", inet_ntoa(pParams->IP), ntohs(pParams->port), pParams->s);}
      

  3.   

    //建立一个线程处理请求
    static PARAMS params;//线程处理函数的参数
    params.IP = clientAddr.sin_addr;
    params.port = clientAddr.sin_port;
    params.s = sClient;HANDLE hThread=(void *)_beginthread(ThreadFunc,0,(void *)&params);
    CloseHandle(hThread);你定义的params是用于存储IP/Port/Sock信息的,但是无论连入了多少个客户端,你好像都只有这样一个变量,那么这个结构里就只能保存下最后一个的信息了,包括Soctet在内,之前的都被丢失了。
    把params定义成数组吧,或者把结构修改成链表形式的,要确保每一个Socket有一个单独的变量。
      

  4.   

    sClient = accept(listenSocket, (struct sockaddr *)&clientAddr, &nAddrLen); if(sClient == SOCKET_ERROR)
    {
    err = WSAGetLastError();
    printf("\naccept错误,错误代码:%d\n",err);
    return;
    }
    else
    {
    printf("接受来自%s的连接请求\n",inet_ntoa(clientAddr.sin_addr)); //建立一个线程处理请求
    static PARAMS params;

    //线程处理函数的参数
    params.IP = clientAddr.sin_addr;
    params.port = clientAddr.sin_port;
    params.s = sClient; HANDLE hThread=(void *)_beginthread(ThreadFunc,0,(void *)&params);
    CloseHandle(hThread);
    ============================================================================
    这里是否为一个循环??? 如果否那么就只能一个CLIENT连接进来了!!
      

  5.   

    建议你用CPtrList建一个链表,把跟各个客户端通讯的socket的指针写到链表里,这样比较方便
      

  6.   

    while (true)
    {
    sClient = accept(listenSocket, (struct sockaddr *)&clientAddr, &nAddrLen)
    .............
    ...........
    }  加循环就可以了
      

  7.   

    几位说的对,是static的问题。
      

  8.   

    谢谢大家,特别是 maplevsred(残桓枫雪)
    贴出之后我也发现了这个问题,就是static变量的问题,多线程是共用的,而我只是传了一个指针给ThreadFunc,每次都改为最后一个socket的ID
    我的修改如下:
    PARAMS tmpParams;
    memcpy(&tmpParams,pvoid,sizeof(PARAMS));
    每个线程拷贝一份就好了