下面的这段程序是一个winsock的多线程的例子。方法可能很土,还请大家指点。
我先在服务器上开一个socket用来listen,用来支持最多10个客户的连接,如下,我用了一个循环,一旦accept一个连接之后,就用CreateThread建立一个线程,用来处理该连接上数据的收发等问题。
我定义了线程函数DWORD WINAPI ThreadFunc(LPVOID pvParam)
线程函数里面的参数类型LPVOID好象是固定的,然后我想通过该参数把accept产生的socket传递过去。
于是我用如下方法:
sAccepted[iAccepted] = accept(srv, \
 (sockaddr *)&addr_accept[iAccepted],&iAddrLen);  CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
程序运行到此就出现访问未知内存错误了。请大家指点,另外大家能否提供利用多线程支持多客户的更好的方法,消息机制或怎么样的?用个循环感觉是太土了。
#include "stdafx.h"
#include "winsock.h"DWORD WINAPI ThreadFunc(LPVOID pvParam);int main(int argc, char* argv[])
{
SOCKET srv;
WSADATA wsd; WSAStartup(MAKEWORD(1,1),&wsd);
    srv = socket(AF_INET,SOCK_STREAM,0); sockaddr_in srv_addr;
srv_addr.sin_family = AF_INET;
srv_addr.sin_addr.S_un.S_addr = inet_addr("10.40.59.88");
srv_addr.sin_port = htons(8080); bind(srv,(sockaddr *)&srv_addr,sizeof(sockaddr_in));
    listen(srv,10);    SOCKET sAccepted[10];
sockaddr_in addr_accept[10];
LPDWORD lpThread;
    int iAccepted = 0;
int iAddrLen;
iAddrLen = sizeof(sockaddr_in);
while (iAccepted < 10)
{
         sAccepted[iAccepted] = accept(srv, \
 (sockaddr *)&addr_accept[iAccepted],&iAddrLen);  CreateThread(NULL,0,ThreadFunc, \
(LPVOID)sAccepted[iAccepted],0,lpThread);
 
 iAccepted++;
} return 0;
}DWORD WINAPI ThreadFunc(LPVOID pvParam)
{
DWORD dwResult = 0;
SOCKET s;
s=(SOCKET)pvParam; char *strBuf = new char[1000];
recv(s,strBuf,sizeof(strBuf),0);
return dwResult;
}

解决方案 »

  1.   

    SOCKET sAccepted[10];
    这是个局部变量,传到线程函数里去岂不糟糕?另外推荐你用非阻塞模式下的socket...有4种I/O模型可供选择。
    最简单的方法莫过于从CAsyncSocket派生一个类,重载
    OnAccept, OnRecieve, OnSend, OnClose等函数,这个类本身就
    包装的异步socket,用的事件模式,对于一般的小型应用足够。
    如果要求很高,就用I/O完成端口模型好了
      

  2.   

    sAccepted[iAccepted] = accept(srv, \
     (sockaddr *)&addr_accept[iAccepted],&iAddrLen);  CreateThread(NULL,0,ThreadFunc, \
    (LPVOID)sAccepted[iAccepted],0,lpThread);改为:
    SOCKET s;s = accept(srv, (sockaddr *)&addr_accept[iAccepted],&iAddrLen);
    sAccepted[iAccepted] = s;
    CreateThread(NULL,0,ThreadFunc, \
    (LPVOID)&s,0,lpThread);
      

  3.   

    线程之间不能直接传socket,要传句柄才行,我就是犯过此错误。
    用Detach()从socket中分离SOCKET传到接收线程中,用Attach()附加到生成的socket中就不会出错了,有问题QQ;39446783
      

  4.   

    多谢大家!
     livelivelive(神仙般的生活) ( ) 
    我在单位只能通过sockxp上QQ,速度太慢,加了几次未成功。我有点疑问。socket在BSD中好象其实也就是个int型的数字,来代表一个socket。
    如int s=socket(.....)
    在Winsock里面,SOCKET是不是已经不是int了,而是一个结构?
      

  5.   

    //改成以下代码看看while (iAccepted < 10)
    {
             sAccepted[iAccepted] = accept(srv, \
     (sockaddr *)&addr_accept[iAccepted],&iAddrLen);
    if(sAccepted[iAccepted]=INVALID_SOCKET;//这句话好我加的
       continue;  CreateThread(NULL,0,ThreadFunc, \
    (LPVOID)sAccepted[iAccepted],0,lpThread);
     
     iAccepted++;
    }