winsock编程,采用select实现面向连接一个服务器和多个客户端的收发数据,运行时产生错误,劳驾帮忙看一下:
#include<iostream.h>
#include<winsock2.h>
#define DEFAULT_PORT 4000
void WINAPI SendOut();
char info[255];
bool isConnect;
SOCKET sServSock= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
fd_set fds;
void main()
{
WORD wVersionRequested=MAKEWORD(2,2); //初始化winsock
WSADATA wsaData;
WSAStartup(wVersionRequested,&wsaData); //SOCKET sServSock= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

sockaddr_in addr;
int nSockErr;
int nNumConns=0;
SOCKET sClient;
sockaddr ConnAddr;
int nAddrLen=sizeof(sockaddr);
addr.sin_family=AF_INET;
addr.sin_port =htons(DEFAULT_PORT);
addr.sin_addr.s_addr=htonl(INADDR_ANY); if(bind(sServSock,(LPSOCKADDR)&addr,sizeof(addr))==SOCKET_ERROR)       //SOCKET_ERROR=-1
{
nSockErr=WSAGetLastError();
} if(listen(sServSock,5)==SOCKET_ERROR)
{
nSockErr=WSAGetLastError();
} //fd_set fds;
FD_ZERO(&fds);
FD_SET(sServSock,&fds); CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)SendOut,NULL,0,NULL); //发送数据 bool bRunning=1;
do{
fd_set readfds;
CopyMemory(&readfds,&fds,sizeof(fd_set));
if(select(0,&readfds,NULL,NULL,NULL)>0)
{
for(int i=readfds.fd_count-1;i>=0;i--)//顺序处理每一个有事件发生的套接字
{
if(readfds.fd_array[i]=sServSock)
{
sClient=accept(sServSock,&ConnAddr,&nAddrLen);
if(sClient==INVALID_SOCKET){
bRunning=false;
break;
}
cout<<"Client Accept Successfull."<<endl;
FD_SET(sClient,&fds); //将与新客户端对应的套接字加入select函数监视的集合
}
else//与客户端对应的套接字有事件发生说明有数据需要接收
{
char in[255];
sClient=readfds.fd_array[i];
if(recv(sClient,in,255,0)!=SOCKET_ERROR)
cout<<"\b<"<<in<<endl<<">";
else{
cout<<"\b<"<<"client exit"<<endl<<">";
FD_CLR(sClient,&fds); //将该套接字移出select集合
closesocket(sClient);
}
}
}
}
}while(bRunning);
WSACleanup();
}void WINAPI SendOut()
{
do
{
cin.getline(info,255);
if(!strcmp(info,"bye"))break;
cout<<">";
for(int i=fds.fd_count-1;i>=0;i--)
{
if(fds.fd_array[i]!=sServSock)
{
fd_set writefds;
FD_ZERO (&writefds);
FD_SET(fds.fd_array[i],&writefds); if(select(0,NULL,&writefds,NULL,NULL)>0)
send(fds.fd_array[i],info,255,0);
}
}
}while(true);

closesocket(sServSock);
}


解决方案 »

  1.   

    发生什么错误???网络错误使用WSAGetLastError来获得
      

  2.   

    SOCKET sServSock= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    先于
    WSAStartup(wVersionRequested,&wsaData);
    执行,套接字不能成功创建。加一句进行检测:if (sServSock == SOCKET_ERROR)
    {
       printf("Last Error: %d\n", GetLastError());
       return;
    }
      

  3.   

    不建议把  sServSock 当作全局来用!!SOCKET sServSock= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
      

  4.   

    SOCKET sServSock= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    --
    这个语句放在这里不妥,因为这个时候你的SOCKET 库都没有初始化,怎么可以创建SOCKET,所有这是的sServSock不是一个创建成功的SOCKET.
    而应该在这里放一个定义,具体创建应该在main里面初始化SOCKET库之后.
    所有 这里应该:
    SOCKET sServSock = -1;
    然后在main里面(在WSAStartup(wVersionRequested,&wsaData);之后)加一个:
    sServSock= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    就OK了.
    --
    不然你在if(bind(sServSock,(LPSOCKADDR)&addr,sizeof(addr))==SOCKET_ERROR) 这里会产生错误所你的sServSock不是一个SOCKET.nSockErr=10038 (WSAENOTSOCK)