数据接收问题.....100分大奉送....不够再开贴送分

peter9606 2004-04-19 02:48:21
int CServiceThread::Run()
{
sockaddr_in serverAddr;
sockaddr_in clientAddr;
int addinlength = sizeof(clientAddr);
int nRet ;
int nEc ;
SgmHeader sgmHeader1 ;
SgmHeader sgmHeader2 ;
RplHeader rplHeader ;

WORD wVersion = MAKEWORD(1,1) ;
WSADATA wsaData ;


DWORD time1,time2 ;

WORD w ;
DWORD ww ;

BOOL Frame_flg = TRUE ;


nRet = WSAStartup(wVersion,&wsaData) ;


serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(m_Port);
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);


if (nRet != 0) {
WSACleanup() ;
return -1 ;
}

if (wVersion != wsaData.wVersion) {
WSACleanup() ;
return -1 ;
}

m_ListeningSocket = socket (AF_INET,SOCK_STREAM,IPPROTO_TCP) ;

if (m_ListeningSocket < 0) {
WSACleanup() ;
return -1 ;
}

nRet = bind(m_ListeningSocket,(SOCKADDR *)&serverAddr,sizeof(serverAddr));

if(nRet == SOCKET_ERROR){
closesocket(m_ListeningSocket);
WSACleanup();
return -1;
}

listen(m_ListeningSocket,1);

m_ServiceSocket = accept(m_ListeningSocket,(sockaddr *)&clientAddr,&addinlength);

fd_set readfds ;
readfds.fd_count = 1 ;
readfds.fd_array[0] = m_ServiceSocket ;

const char FAR* optival ;
int nByte = 300000 ;

optival = (const char *)&nByte ;
setsockopt (m_ServiceSocket,SOL_SOCKET,SO_RCVBUF,optival,4) ;

u_long FAR argp ;
argp = 1 ;
ioctlsocket (m_ServiceSocket,FIONBIO,&argp) ;


while (1) {

if (select (0,&readfds,NULL,NULL,NULL) == 1) {
::AfxMessageBox("难道我又接收到了么?",MB_OK ¦MB_ICONERROR);
}

return CWinThread::Run();
}

请问这个流程有什么错误么?

我在实际运行的时候 第一次接收电文 很好很正常 服务器端启动以后等待接收客户端来的数据.
但是在第一次处理完数据后,不等客户端发送数据就又弹出了"难道我又接收到了么?"的对话框.我不知道这里到底是怎么回事
希望高人指点
万分感谢!


我都在if (select (0,&readfds,NULL,NULL,NULL) == 1) {
::AfxMessageBox( "难道我又接收到了么? ",MB_OK ¦MB_ICONERROR);
}
里面接收数据的呀处理完后发送
第一次接收的时候好好的
但是第二次 客户端没有发送数据呢
就服务器就直接弹出 对话框了(AfxMessageBox( "难道我又接收到了么? ",MB_OK ¦MB_ICONERROR);
)可是却什么都没有接收到.



...全文
112 点赞 收藏 13
写回复
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
flyinwuhan 2004-04-19
不要把分给我的马甲!
回复
flyinwuhan 2004-04-19
你的判断方式是错的---select用错了

FD_ZERO(&fdread);
FD_SET(s,&fdread); //加入套接字,详细定义请看winsock2.h
if(select(0,%fdread,NULL,NULL,NULL)>0
{
//成功
if(FD_ISSET(s,&fread) //是否存在fread中,详细定义请看winsock2.h
{
//是可读的
}
}
回复
暗黑帝国 2004-04-19
没有revc()函数?????
回复
soft8848 2004-04-19
>>判断readfds中所指定的Socket缓冲区是不是可读
不是这么判断的啦
下面给出Delphi的代码,我对VC不熟:-(
FD_ZERO( fdsRead );
FD_SET( MainSock, fdsRead );
if select( 0, @fdsRead, nil, nil, @timeout ) > 0 then
begin
if FD_ISSET( MainSock, fdsRead ) then
begin
s := accept( MainSock, nil, nil );
if s <> INVALID_SOCKET then
begin
AThread := YClientThread.Create( TRUE );
AThread.ChildSock := s;
AThread.OnReceive := FOnReceive;
AThread.Resume;
end;
end; // for "if FD_ISSET( sock, fdsRead )..."
end; // for "if select( 0, @fdsRead, nil, nil, @timeout ) > 0..."
回复
zxq80 2004-04-19
mark
回复
peter9606 2004-04-19

实际的操作中我是做了 recv的
但是就是在recv后就出现了这样的情况,希望大侠给指点
回复
dinghui96 2004-04-19
只有select,没有接收呀。
回复
fzd999 2004-04-19
楼主你好,消息收到。

select(0,&readfds,NULL,NULL,NULL)
套接字(Socket)的实质是一段内核缓冲区。
select这个函数的作用是判断readfds中所指定的Socket缓冲区是不是可读。在收到数据后,假如对Socket执行过recv之类的接受函数,那么缓冲区随即会被清空,否则缓冲区就始终是可读状态,而select就会立即返回1。
楼主你不妨在select返回之后执行一下recv,然后看看情况如何。
回复
peter9606 2004-04-19
en
难道select函数不是在监视 是否有可以利用的数据到达么?
回复
王绍全 2004-04-19
select不是接收,接收应该用 recv() 函数。
回复
peter9606 2004-04-19
另 : 1,2问题都有向应的对策,我现在仅仅是想验证一下Winsock的实现,所以写的有些仓促了.
不惜赐教
回复
peter9606 2004-04-19
请问 为什么 会 "select (0,&readfds,NULL,NULL,NULL) 函数会马上返回,你的MessageBox当然会弹出来。"
我很想知道这个原因
谢谢
回复
fzd999 2004-04-19
用程序员的说法,你的代码非常的“不专业”,不专业到我根本没办法替你改。

问题主要有这几个方面:
1 MessageBox是会造成线程挂起的,网络传输应用中最好采用OutputDebugString或者日志文件。
2 你每次Run都执行WSAStartup,可是你在函数结束之时WSAClean了吗?
3 select (0,&readfds,NULL,NULL,NULL) 函数会马上返回,你的MessageBox当然会弹出来。
4 CServiceThread这个类名看起来象是一个线程,那么如果这是一个线程回调,你对内存的操作进行了同步吗?
5 最好采用非阻塞模型进行网络通讯,select这个函数很不好用。
回复
发动态
发帖子
网络编程
创建于2007-09-28

1.8w+

社区成员

VC/MFC 网络编程
申请成为版主
社区公告
暂无公告