winsock select()ing 运行时错误
Posted
技术标签:
【中文标题】winsock select()ing 运行时错误【英文标题】:winsock select()ing runtime error 【发布时间】:2010-11-29 07:46:36 【问题描述】:我正在尝试解决我之前发布的关于同步聊天消息的问题,一位成员向我指出了 select() 函数的方向。我阅读了 Beej 网络指南下的this 部分,并尝试编写在 windows 下给出的示例。它编译得很好,但是当我去测试它时,在将端口号输入程序后,程序崩溃并显示我的错误消息"-Select error"
-。我不确定如何让这个工作,请指教。
服务器.cpp
#include <iostream>
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
using namespace std;
const int winsockver = 2;
int PORT;
int fdmax;
char buffer[80];
int main(void)
//*********************************************
fd_set master;
fd_set temp;
SOCKET newfd;
struct sockaddr_in connected_client;
//*********************************************
WSADATA wsadata;
if (WSAStartup(MAKEWORD(winsockver,0),&wsadata) == 0 )
cout<<"-Winsock Initialized." << endl;
cout<<"Enter PORT:";
cin>> PORT;
//--------------------------------------------------------------------
struct sockaddr_in server_info;
server_info.sin_family = AF_INET;
server_info.sin_port = htons(PORT);
server_info.sin_addr.s_addr = INADDR_ANY;
SOCKET serv_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if ( serv_sock != INVALID_SOCKET)
if ( bind(serv_sock,(sockaddr*)&server_info,sizeof(server_info)) != -1 )
char yes = '1';
if ( setsockopt(serv_sock,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes)) != SOCKET_ERROR)
cout<<"-Binding Successful." << endl;
if ( listen(serv_sock,5) != -1 )
cout<<"-Listening for incoming connections." << endl;
FD_SET(serv_sock,&master);
fdmax = serv_sock; // keeping track of the largers sockfd, at this moment its serv_sock
//#########################################################
for(;;)
temp = master; // copying to temp the master set
if (select(fdmax+1,&temp,NULL,NULL,NULL) == -1 )
cout<<"-select error." << endl;
//run through existing connections looking for data to read
for (int i = 0; i <= fdmax; i++)
if (FD_ISSET(i,&temp))//we have one
if (i == serv_sock)//handle new connections
int size =sizeof(connected_client);
newfd = accept(serv_sock,(sockaddr*)&connected_client,&size);
if ( newfd == -1 )
cout<<"-Accepted an invalid socket from newfd." << endl;
else//accept has returned a valid socket descriptor and we add it to the master
FD_SET(newfd,&master);
if (newfd > fdmax )
fdmax = newfd;
char *connected_ip= inet_ntoa(connected_client.sin_addr);
cout<<"-Select server new connection from " << connected_ip << " " << endl;
else
//handle data from a client
int bytes_in;
bytes_in = recv(i,buffer,sizeof(buffer),0);
if ( bytes_in <= 0 )
if (bytes_in == 0 )
cout<<"-Connected socket " << i << ",disconnected " << endl;
else
cout<<"-Socket error." << endl;
closesocket(i);
FD_CLR(i,&master); //remove from master set.
else
//we get data from a client
for (int j=0; j <= fdmax; j++ )
//send to everyone
if (FD_ISSET(j,&master))
//except the listener and ourself
if ( (j != serv_sock) && (j != i) )
if ( send(j,buffer,sizeof(buffer),0) == -1 )
cout<<"-Sending error" << endl;
//#########################################################
//--------------------------------------------------------------------
else
cout<<"-Unable to Initialize." << endl;
if ( WSACleanup() != -1 )
cout<<"-Cleanup Successful." << endl;
return 0;
【问题讨论】:
只是一个提示:不要检查select()
返回值是否与 -1 相比,而是与 SOCKET_ERROR 相比。一旦出现错误,显示WSAGetLastError()
结果。
干杯西蒙娜`
【参考方案1】:
您的文件描述符集未正确初始化,因此当您对其调用FD_SET()
时,它们仍然包含垃圾。
您应该在开始使用它们之前调用FD_ZERO()
来初始化它们:
FD_ZERO(&master);
FD_SET(serv_sock, &master);
fdmax = serv_sock;
【讨论】:
我没想到,这就是 Frederic 的原因。再次感谢您。以上是关于winsock select()ing 运行时错误的主要内容,如果未能解决你的问题,请参考以下文章
Winsock 错误 429:activeX 组件无法创建对象