紧急求救,使用winsock的thread问题

kaku_you 2003-01-15 02:02:59
我的程序要通过telnet连接31台使用telnet server的服务器,我使用如下方法进行处理

1.继承CWinThread在里面添加SOCKET类型的成员net

2.发送函数使用
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(netsock,&writefds);
int sv = ::select(FD_SETSIZE, NULL, &writefds, NULL, &timeout);
if( sv<=0 )return;
::send(netsock,(LPCSTR)cmd,cmd.GetLength(), 0);
的程序来发送

3.接收函数使用
fd_set readfds;
FD_ZERO( &readfds );
FD_SET ( netsock,&readfds );
int sv=::select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
if( sv <= 0 )return;
int recv_size = ::recv(netsock,buf,buf_len, 0);
的程序来接收

连接4,5台服务器没有任何问题,一连接31台的服务器就会经常发生某几个recv函数返回-1,我用WSAGetLastError函数取得的err id号是183,我想问大家,我的winsocket方法是不是不对,在多线程下是不是有正确的使法?
...全文
33 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
yydyqy 2003-01-17
  • 打赏
  • 举报
回复
up
kaku_you 2003-01-17
  • 打赏
  • 举报
回复
关于183,我发现一个可笑的情况


#include <afx.h>
#include <stdio.h>
#include <winsock2.h>
int main(){
FILE *fp = fopen( "c:\\test.log","a" );
if( fp!=NULL )
{
fprintf( fp,"----TEST----\n" );
fclose( fp );
}
printf( "PRINT ERR : %d\n" , WSAGetLastError() );

return 0;
}

如果文件本身没有就是0,再运行一回,就是183,因为我的程序基本适用上面的方法打印log文件。我想,这个函数根本就没能取出正确的错误吧
cxu123 2003-01-17
  • 打赏
  • 举报
回复
恐怕你的其它代码有问题,错误代码183很奇怪
shitalone 2003-01-17
  • 打赏
  • 举报
回复
mark
kaku_you 2003-01-17
  • 打赏
  • 举报
回复
太谢谢了,能不能解决还不知道,试验环境太差,没法验证,为什么我总是遇到这样的事
cxu123 2003-01-17
  • 打赏
  • 举报
回复
183 Cannot create a file when that file already exists. ERROR_ALREADY_EXISTS

while (1) {
FD_ZERO( &readfds );
FD_SET ( netsock,&readfds );
sv=::select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
if (sv>0&&FD_ISSET(netsock, &readfds)) {
recv_size = ::recv(netsock,buf,buf_len, 0);
...// telnet function here
} else
...
}

你的方法不好,最好是如上这么写,连timeout也不要,线程进入select等待一直等到数据才返回,然后调用你的TELENET功能模块,调用完线程重新进入select等待。如果出错或对方关闭SOCKET才结束线程。

lchlovely 2003-01-17
  • 打赏
  • 举报
回复
up
kaku_you 2003-01-17
  • 打赏
  • 举报
回复
另外问一句,183是什么错误?
kaku_you 2003-01-17
  • 打赏
  • 举报
回复
是不是我这么写可以作为一种解决方法?

fd_set readfds;
int recv_size;
int sv;

while (1) {
FD_ZERO( &readfds );
FD_SET ( netsock,&readfds );
sv=::select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
if ( sv>0 && FD_ISSET(netsock, &readfds) )
break;
}
recv_size = ::recv(netsock,buf,buf_len, 0);
kaku_you 2003-01-17
  • 打赏
  • 举报
回复
对不起,还没解决,用了公司里的10几台安装windows2000的机器,趁着周末全都装了一个叫UWIN的模拟UNIX的软件来测试,解决了再说吧
HongHuer 2003-01-17
  • 打赏
  • 举报
回复
楼主,
怎么解决的啊?

说说。
cxu123 2003-01-16
  • 打赏
  • 举报
回复
你的代码不全,正确的用法应该是

fd_set readfds;
int recv_size;
int sv;

while (1) {
FD_ZERO( &readfds );
FD_SET ( netsock,&readfds );
sv=::select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
if (sv>0&&FD_ISSET(netsock, &readfds)
recv_size = ::recv(netsock,buf,buf_len, 0);
else
...
}

每次调用前重新FD_ZERO( &readfds ); FD_SET ( netsock,&readfds );另外你的方法不好,应该把所有的netsock放在一起调select,用FD_ISSET检查那个socket可以读,然后调相应的线程,这样效虑高,select最大的缺点是占CPU时间大,不过你是Telenet程序,就没有关系了。按道理select应该是thread safe,但你的错误返回183很怪,不得不怀疑
kaku_you 2003-01-16
  • 打赏
  • 举报
回复
对不起,如果某个thread把别的thread的socket状态取走了,那被取走的thread还能继续使用select取得它自己的socket状态吗?
如果您方便的话,能留下mail地址吗?

我的mail:: kaku_you@hotmail.com
kaku_you 2003-01-16
  • 打赏
  • 举报
回复
to cxu123
不好意思,我还是没明白

fd_set readfds;
FD_ZERO( &readfds );
FD_SET ( netsock,&readfds );

我这里只检查本线程的socket的状态,我想应该不会返回别的线程的socket吧,我只是觉得是这样,难道select不是thread safe的吗?
还恳请指教
HongHuer 2003-01-16
  • 打赏
  • 举报
回复
up
cxu123 2003-01-16
  • 打赏
  • 举报
回复
需要在select返回后用FD_ISSET测一下是不是本线程的netsock ready.不是本县城的netsock ready 你调RECV当然返回-1。
yanhuahui 2003-01-15
  • 打赏
  • 举报
回复
服务器试着用io完成端口,客户用异步事件选择......
这个比较稳定...
kaku_you 2003-01-15
  • 打赏
  • 举报
回复
我的程序要通过telnet连接31台使用telnet server的服务器,我使用如下方法进行处理

1.继承CWinThread在里面添加SOCKET类型的成员netsock

2.发送函数使用
fd_set writefds;
FD_ZERO(&writefds);
FD_SET(netsock,&writefds);
int sv = ::select(FD_SETSIZE, NULL, &writefds, NULL, &timeout);
if( sv<=0 )return;
::send(netsock,(LPCSTR)cmd,cmd.GetLength(), 0);
的程序来发送

3.接收函数使用
fd_set readfds;
FD_ZERO( &readfds );
FD_SET ( netsock,&readfds );
int sv=::select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
if( sv <= 0 )return;
int recv_size = ::recv(netsock,buf,buf_len, 0);
的程序来接收

连接4,5台服务器没有任何问题,一连接31台的服务器就会经常发生某几个recv函数返回-1,我用WSAGetLastError函数取得的err id号是183,我想问大家,我的winsocket方法是不是不对,在多线程下是不是有正确的使法?

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧