我在编写基于C/S的一个网络通信程序。Client,Server端都能够初始化成功,我是准备当服务端开启服务等待客户端的请求连接消息,一旦有这种请求,服务端马上开启一个客户端线程进行操作,但是就是在这个线程里面出现了一点点问题。下面是我的服务启动线程以及客户端请求处理线程。
UINT LoadWinSock(LPVOID lpParam)
{
int         nZero;
int         iAddrSize;
char        szString[255];
char        szClientIP[81];
sockaddr_in local,client;
myStruct myStructure;
Listen = WSASocket(AF_INET,SOCK_STREAM,IPPROTO_IP,NULL,0,SOCK_STREAM);
if (Listen == SOCKET_ERROR)
{
//szString.Format("socket() failed: %d",WSAGetLastError());
sprintf(szString,"socket() failed: %d",WSAGetLastError());
AfxMessageBox(szString );
return 1;
} // 设置server端信息
local.sin_addr.s_addr = htonl(INADDR_ANY);//将主机的无符号长整形数转换成网络字节顺序
local.sin_family = AF_INET;
local.sin_port = htons(gPort);//消除字节存储顺序差异可能带来的错误 // 绑定到socket
if (bind(Listen,(struct sockaddr *)&local,sizeof(local)) == SOCKET_ERROR)
{
//szString.Format("bind() failed: %d\n", WSAGetLastError());
sprintf(szString,"bind() failed: %d\n",WSAGetLastError());
AfxMessageBox(szString);
return 1;
} //减小CPU的利用率
nZero = 0;
setsockopt(Listen,SOL_SOCKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero)); listen(Listen,5); iAddrSize = sizeof(client); while(TRUE)
{
if((Socket = accept(Listen,(struct sockaddr *)&client,&iAddrSize)) != INVALID_SOCKET)
{
       myStructure.Socket = Socket;
myStructure.hWnd = hServerWnd; memset(szClientIP,'\0',sizeof(szClientIP));
sprintf(szClientIP,"%s",inet_ntoa(client.sin_addr)); AfxBeginThread(ClientThread,NULL);
}
else
return 1;
}
return 0;
}UINT ClientThread(LPVOID lpParam)
{
HWND     hWnd;
SOCKET   MySocket;
DWORD    iRecv,iLength,iRet;
int      iUpdates;
char     szMessage[2049];
timeval  timeout;
FD_SET   SocketSet;
myStruct *myStructure; // 分析参数
myStructure = (myStruct *)lpParam;
MySocket    = myStructure->Socket;//在这个地方调试的时候出现错误,不知道是不是实例化lpParam有问题
hWnd        = myStructure->hWnd; // 设置超时值
timeout.tv_sec = 0; // 秒
timeout.tv_usec = 0; // 微秒 // 设置Socket集合
SocketSet.fd_count = 1;
SocketSet.fd_array[1] = MySocket; while(TRUE)
{
iRet = select(0,&SocketSet,NULL,NULL,&timeout); if(iRet != 0)
{
memset(szMessage,'\0',sizeof(szMessage));
// 阻塞方式调用recv()
iRecv = recv(MySocket,szMessage,2048,0);
szMessage[iRecv] = '\0';
}
// 是不是"REFRESH"消息
if (strncmp(szMessage,"REFRESH",7) == 0)
{
// 捕获并且发送桌面的更新的区域
iUpdates = SendRegionDisplay(hServerWnd,MySocket);
}
else if (strncmp(szMessage,"RESOLUTION",10) == 0)
{
SendResolution(MySocket);
}
// 检查是否是DISCONNECT消息
else if (strncmp(szMessage,"DISCONNECT",10) == 0)
{
fChange = FALSE;
fDIBitmap = FALSE; pGdiNode = GdiStart.pNext;
while (pGdiNode)//释放节点资源
{
free(pGdiNode->Gdi.pDIBitmap);
free(pGdiNode->Gdi.pDIBChangeStart);
pGdiNode->Gdi.fDIBitmap = FALSE;
pGdiNode->Gdi.fChange = FALSE;
pGdiNode = pGdiNode->pNext;
}
// 停止查询,相当于结束该线程
break;
}
}
closesocket(MySocket);
return 0;
}
就是在ClientThread()里面的“MySocket = myStructure->Socket;”出错,DEBUG下的错误是“Server.exe中的0x0041a607处出现异常:0xC0000005:读取位置0x00000000时发生访问冲突”这里由于的分都用光了,以后可以另外开贴追加

解决方案 »

  1.   

    AfxBeginThread(ClientThread,NULL); 你这一句并没有把参数传进来,你传的是NULL, 肯定出错呀
      

  2.   

    AfxBeginThread(ClientThread,NULL); 第二个参数NULL就是传给第一个参数指定的函数ClientThread调用的参数,即UINT ClientThread(LPVOID lpParam)的lpParam参数,而在ClientThread函数中,你没有对lpParam指针判断是否为空,就直接使用:
    myStructure = (myStruct *)lpParam;
    MySocket = myStructure->Socket;//在这个地方调试的时候出现错误,不知道是不是实例化lpParam有问题
    hWnd = myStructure->hWnd;
    所以崩溃。