各位老师们好,接受不到数据

aaa12213 2012-08-04 10:57:26


//////////////////////////////////////////////////////
// select.cpp文件


#include <stdio.h>


#include <winsock2.h>
#pragma comment(lib, "WS2_32") // 链接到WS2_32.lib

class InitWinSock
{
public:
InitWinSock(BYTE minorVer = 2, BYTE majorVer = 2)
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, majorVer);
if(::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~InitWinSock()
{
::WSACleanup();
}
};


#include <windows.h>
#include <process.h>




InitWinSock theSock;

FD_SET g_fdRead;

FD_SET g_allSet; //全集

SOCKET g_sListen;



unsigned long _stdcall ThreadFun(void*)
{
while(1)
{

g_fdRead=g_allSet;

timeval timeval;

timeval.tv_sec=0;
timeval.tv_usec=0;

int nRet = ::select(0, &g_fdRead, NULL, NULL, &timeval);

printf("%d\n",nRet);

if(nRet<=0)
{
Sleep(500);
continue;
}

//检测是否有新连接,或者有数据传输
if(FD_ISSET(g_sListen,&g_allSet))
{
SOCKET stmp=NULL;
sockaddr_in sockadd;
int nLen=sizeof(sockaddr_in);

stmp=accept(g_sListen,(sockaddr*)&sockadd,&nLen);

FD_SET(stmp,&g_allSet);

}

//可以运行到for 循环中!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!


for(int i=0;i< g_fdRead.fd_count;i++)
{

if(FD_ISSET(g_fdRead.fd_array[i],&g_allSet))
{

SOCKET stmp=NULL;
sockaddr_in sockadd;
int nLen=sizeof(sockaddr_in);
char buf[200];
ZeroMemory(buf,sizeof(buf));
recv(g_fdRead.fd_array[i],buf,sizeof(buf),0);

printf("接受数据为:%s\n",buf);
}


}


Sleep(500);

} //end while


return 0;

}


int main()
{


USHORT nPort = 9585; // 此服务器监听的端口号

// 创建监听套节字
g_sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(nPort);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
// 绑定套节字到本地机器
if(::bind(g_sListen, (sockaddr*)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf(" Failed bind() \n");
return -1;
}
// 进入监听模式
::listen(g_sListen, 5);



FD_ZERO(&g_allSet);

FD_ZERO(&g_fdRead);


FD_SET(g_sListen,&g_allSet);

// HANDLE hThread=(HANDLE)_beginthreadex(NULL,0,ThreadFun,NULL,0,NULL);

HANDLE hThread=CreateThread(NULL,0,ThreadFun,0,0,NULL);

WaitForSingleObject(hThread,-1);

CloseHandle(hThread);



return 0;
}






问题代码中已经说了

for循环是可以进入的,数据就是接受的为空!


问题2:由于select是非堵塞的, 但是 select还是有些特殊,accept是可以根据其返回值来判断,

套接字是否合法。

呵呵

有的非堵塞模式,是不能根据的!!

这个是个人体会。


关键是我的第一个问题。

谁帮我解答,谢谢
...全文
164 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiaohuh421 2012-08-05
  • 打赏
  • 举报
回复

FD_ZERO(&fdWrite);
每次select前,要调用FD_ZERO清标记.
aaa12213 2012-08-04
  • 打赏
  • 举报
回复
亲,

第一个参数

nfds [in]
Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.

msdn

第二个,是否是时间过短导致的,我试试


[Quote=引用 1 楼 的回复:]

timeval.tv_sec=0;
timeval.tv_usec=0;
int nRet = ::select(0, &g_fdRead, NULL, NULL, &timeval);
----------------------------------------------------------
(1) select的第一个参数是错误
(2) 超时时间一般不设置……
[/Quote]
wqkjj 2012-08-04
  • 打赏
  • 举报
回复
timeval.tv_sec=0;
timeval.tv_usec=0;
int nRet = ::select(0, &g_fdRead, NULL, NULL, &timeval);
----------------------------------------------------------
(1) select的第一个参数是错误
(2) 超时时间一般不设置为0秒
(3) 操作系统的函数实现的功能基本是可以相信的,尤其是操作系统厂商提供的技术资料说明。不可信的是市面上一些粗制滥造的书。
aaa12213 2012-08-04
  • 打赏
  • 举报
回复
只有一个客户端啊,已经连接上了,


执行了for循环后,尽管没有接受到数据,可以说明,

客户端有数据发送!!!

再执行几次后,就会进入这个if块。

这个if块是用来检测有新的客户端连接的,

已经连接上了,为什么还会这样啊?

我把客户端代码贴出来


//////////////////////////////////////////////////////////
// TCPClient.cpp文件


#include "common/InitSock.h"
#include <stdio.h>
CInitSock initSock; // 初始化Winsock库

int main()
{
// 创建套节字
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(s == INVALID_SOCKET)
{
printf(" Failed socket() \n");
return 0;
}

// 也可以在这里调用bind函数绑定一个本地地址
// 否则系统将会自动安排

// 填写远程地址信息
sockaddr_in servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(9585);
// 注意,这里要填写服务器程序(TCPServer程序)所在机器的IP地址
// 如果你的计算机没有联网,直接使用127.0.0.1即可
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
{
printf(" Failed connect() \n");
return 0;
}
else
{
printf(" Success connect() \n");


}
char buf[100];
memset(buf,0,100);

strcpy(buf,"hello");

while(1)
{
send(s,buf,100,0);

Sleep(1000);

}


// 关闭套节字
::closesocket(s);
return 0;
}







[Quote=引用 3 楼 的回复:]

//检测是否有新连接,或者有数据传输
if(FD_ISSET(g_sListen,&g_allSet))
{
SOCKET stmp=NULL;
sockaddr_in sockadd;
int nLen=sizeof(sockaddr_in);

……
[/Quote]
aaa12213 2012-08-04
  • 打赏
  • 举报
回复
//检测是否有新连接,或者有数据传输
if(FD_ISSET(g_sListen,&g_allSet))
{
SOCKET stmp=NULL;
sockaddr_in sockadd;
int nLen=sizeof(sockaddr_in);

stmp=accept(g_sListen,(sockaddr*)&sockadd,&nLen);

FD_SET(stmp,&g_allSet);

}



当客户端连接后,然后开始接受数据,接受都为空, 再运行几次后,

发现,代码会堵在

这一楼提供的if语句块里

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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