关于网络编程多线程死循环问题

wsig 2010-04-01 12:36:14
关于网络编程多线程死循环问题,我写一个聊天服务器程序,基于TCP的,
WSADATA wsaData;
if( WSAStartup(MAKEWORD(2,2),&wsaData)!=0)//初始化WSA 调用成功则返回0
{
MessageBox(NULL,"初始化失败","",MB_OK);
WSACleanup();
}

SOCKET ServerSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); //SOCK_STREAM 流式套接字
//IPPROTO_TCP TCP协议 用于流式套接字
if(INVALID_SOCKET ==ServerSock)
{
MessageBox(NULL,TEXT("创建套接字失败"),"",MB_OK);
WSACleanup();
}


sockaddr_in server;
server.sin_addr.S_un.S_addr = INADDR_ANY; //本机ip
server.sin_family = AF_INET ; //指定通信协议
BOOL Err;
UINT Port =GetDlgItemInt(hwnd,IDC_PORT,&Err,TRUE);
server.sin_port = htons(Port); //主机字节顺序转成网络字节顺序
if(bind(ServerSock,(LPSOCKADDR)&server,sizeof(server))==SOCKET_ERROR)
{
MessageBox(NULL,TEXT("绑定套接字失败"),"",MB_OK);
closesocket(ServerSock);
}

if(listen(ServerSock,5)==SOCKET_ERROR)
{
MessageBox(NULL,TEXT("监听失败"),"",MB_OK);
closesocket(ServerSock);
}

SetDlgItemText(hwnd,IDC_SYSTEMMSG,TEXT("服务器正在监听....."));


SOCKET TcpSocket;
SOCKADDR_IN TcpClientAddr;
while(1)
{
int alen;
TcpSocket=accept(ServerSock,(SOCKADDR*)&TcpClientAddr,&alen);
if(TcpSocket<0)
{
exit(1);
}
........
}
在上面的循环中为什么会出现死循环呢 我在这个循环中用accept不断接收连接请求,到底哪错了啊
...全文
287 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
eyodo8 2010-04-02
  • 打赏
  • 举报
回复
结贴率才16。67%,lz应该反省下了。
Eleven 2010-04-02
  • 打赏
  • 举报
回复
lz参考socket I/O模型
itjobtxq 2010-04-02
  • 打赏
  • 举报
回复
这是因为accept一直在那里接受连接,所以程序根本不往下执行,所以程序给人像是死了的感觉。如果你用了多线程,不会影响界面的响应。可以使用select来解决这个问题。
wsig 2010-04-02
  • 打赏
  • 举报
回复
有点儿意思哈哈,谢谢wenfengsoftware
wenfengsoftware 2010-04-02
  • 打赏
  • 举报
回复
大体思路。
button按下后开一个线程A负责监视客户端的连接。button事件结束。线程A在不断运行中。
线程A一旦监视到一个连接。再针对这个连接开线程B,一个线程B只负责一个客户端的通信。
可能开多个线程B所以, 要用一个LIST记住线程B的HANDLE(方便在最后关闭时,停止线程)。

A
| | | |......
B B B B......

最后别忘记在程序终止时,停止所有以上开的线程。
wsig 2010-04-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sms88 的回复:]


当然你的界面会无响应啦,你的button按下事件这个处理函数都没有返回出来……
[/Quote]
方便留下邮箱吗,我把工程打包发给你,帮我改下好吗??
jogger007 2010-04-02
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 wenfengsoftware 的回复:]
楼上有道理, 你应该开一个线程进行监视。
[/Quote]
UP
wsig 2010-04-02
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 sms88 的回复:]

当然你的界面会无响应啦,你的button按下事件这个处理函数都没有返回出来……
[/Quote]
那要怎么改才行呢
wenfengsoftware 2010-04-02
  • 打赏
  • 举报
回复
楼上有道理, 你应该开一个线程进行监视。
wsig 2010-04-02
  • 打赏
  • 举报
回复
void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id)
{
case IDC_OK://启动服务
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested=MAKEWORD(2,2);

err=WSAStartup(wVersionRequested,&wsaData);
if(err!=0)
{
return;
}

if(LOBYTE(wsaData.wVersion)!=2||
HIBYTE(wsaData.wVersion)!=2)
{
WSACleanup();
return;
}

//创建用于监听的套接字
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);


SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);

while(1)
{
//等待客户请求到来
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf[100];
sprintf(sendBuf,"welcomee %s to http://www.sunxin.org",
inet_ntoa(addrClient.sin_addr));

//发送数据
send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[100];
//接受数据
recv(sockConn,recvBuf,100,0);

MessageBox(NULL,recvBuf,TEXT(""),MB_OK);
closesocket(sockConn);
}

}
break;
default:
break;
}
}
这是代码,IDC_OK为启动服务,我一点击就会执行上面的代码,然后界面就死了。有什么问题吗
sms88 2010-04-02
  • 打赏
  • 举报
回复
那样改了也不行,可能你们没明白我的意思。我建立的服务器有一个“BUTTON”,我想实现的功能是按下它,服务器就开始监听,然后我响应事件中添加代码,用一个死循环来不断接受用户的连接请求。但是问题出来了,一点BUTTON,界面马上死锁了,不知道是怎么回事。哪位兄弟帮帮我 留下邮箱,我把工程打包发过去,急啊,在此先谢过了。

当然你的界面会无响应啦,你的button按下事件这个处理函数都没有返回出来。你的accept函数也是阻塞的,没有接受到连接的话就一直停在这个语句
wenfengsoftware 2010-04-02
  • 打赏
  • 举报
回复
你在循环里面加个 Sleep(100); 尝试一下。
可能是循环一直在做, CPU没有时间去做其他事情了, 所以你的画面是死掉的现象。
wsig 2010-04-02
  • 打赏
  • 举报
回复
那样改了也不行,可能你们没明白我的意思。我建立的服务器有一个“BUTTON”,我想实现的功能是按下它,服务器就开始监听,然后我响应事件中添加代码,用一个死循环来不断接受用户的连接请求。但是问题出来了,一点BUTTON,界面马上死锁了,不知道是怎么回事。哪位兄弟帮帮我 留下邮箱,我把工程打包发过去,急啊,在此先谢过了。
AIHANZI 2010-04-02
  • 打赏
  • 举报
回复
accept阻塞,建议开启线程
tech_study_00 2010-04-01
  • 打赏
  • 举报
回复
问题在于你的accept里面没有正确设置入口参数Length


accept
The Windows Sockets accept function accepts an incoming connection attempt on a socket.

SOCKET accept (
SOCKET s,
struct sockaddr FAR* addr,
int FAR* addrlen
);

Parameters
s
[in] A descriptor identifying a socket that has been placed in a listening state with the listen function. The connection will actually be made with the socket that is returned by accept.
addr
[out] An optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family established when the socket was created.
addrlen
[out] An optional pointer to an integer that contains the length of the address addr.




SOCKET TcpSocket;
SOCKADDR_IN TcpClientAddr;
while(1)
{
int alen = sizeof(SOCKADDR_IN); // MUST INITIALIZE VALUE HERE!!!
TcpSocket=accept(ServerSock,(SOCKADDR*)&TcpClientAddr,&alen);
if(TcpSocket<0)
{
exit(1);
}
........
}
wsig 2010-04-01
  • 打赏
  • 举报
回复
不行,不知道是不是我VC出问题 我实在找不出原因.
sms88 2010-04-01
  • 打赏
  • 举报
回复

while(1)
{
SOCKET TcpSocket = INVALID_SOCKET;
SOCKADDR_IN TcpClientAddr;
int alen;
TcpSocket=accept(ServerSock,(SOCKADDR*)&TcpClientAddr,&alen);
if(TcpSocket == INVALID_SOCKET )
{
exit(1);
}
........
}
wsig 2010-04-01
  • 打赏
  • 举报
回复
还是不行,界面死锁了,如果在循环中这样就可以
while(true)
{
break;
}
但不能加任何东西,一加就死.
enter333 2010-04-01
  • 打赏
  • 举报
回复
if(TcpSocket<0)
这个改成
if (SOCKET_ERROR == TcpSocket)
{
break;
}
试试。
enter333 2010-04-01
  • 打赏
  • 举报
回复
if(TcpSocket<0)
这个改成
if (SOCKET_ERROR == TcpSocket)
{
exit(1);
}
试试。

18,356

社区成员

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

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