请教套接字编程中的Accept()函数

yangzhenping
博客专家认证
2010-02-26 06:11:00
我用VC++6.0编写服务器代码时,当listen(listener, 5);启用监听之后,进入循环
//
// 无限循环,接受并处理新的连接
//
while (1)
{
//
clientAddressLength = sizeof(clientAddress);
newsocket = accept(listener,(struct sockaddr *)&clientAddress,&clientAddressLength);
//
......下面省略
}
这种方法在控制台下没问题,但是我写的是WIN32 Application,到达执行accept()时,服务器会不断到连接池队列里查询,导致在没有任何连接时,整个程序卡死的现象

有什么办法可以不让程序卡死?
(如果能知道为什么同样的无限循环程序在控制台下不卡死,而在窗口模式下会卡死,那将很感谢您)
...全文
166 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
macrojj 2010-02-27
  • 打赏
  • 举报
回复
有个线程 一直循环去accpet如果 有连接 下一步马上把接收套接字 等数据 给数据处理线程。 然后还在while里等待。
shiweifu 2010-02-27
  • 打赏
  • 举报
回复
多线程把
yuzl32 2010-02-27
  • 打赏
  • 举报
回复
开线程去执行你的“启用监听之后,进入循环”方面的代码,开启线程查看MSDN:_beginthreadex函数,下面简单示例怎么应用。

#include <windows.h>

DWORD g_dwTlsIndex = -1;

unsigned TlsProc1(void *unuse)
{
LPVOID lpValue = NULL;
TlsSetValue(g_dwTlsIndex,(PVOID)1234);//2
Sleep(1000);
lpValue = TlsGetValue(g_dwTlsIndex); //5

printf("TlsProc1:%d\n",(DWORD)lpValue);
return 0;
}

unsigned TlsProc2(void *unuse)
{
LPVOID lpValue = NULL;
TlsSetValue(g_dwTlsIndex,(PVOID)4567);//3
lpValue = TlsGetValue(g_dwTlsIndex); //4

printf("TlsProc2:%d\n",(DWORD)lpValue);
return 0;
}

int main(void)
{
g_dwTlsIndex = TlsAlloc(); // 1
_beginthreadex(NULL,0,TlsProc1,NULL,0,NULL);
_beginthreadex(NULL,0,TlsProc2,NULL,0,NULL);
_getch();
}
junz_1986 2010-02-27
  • 打赏
  • 举报
回复
专门开启一个线程去循环投递消息,不要在主线程中处理
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
引用 11 楼 macrojj 的回复:
都让你不要在界面线程里面accpet了。
你开一个线程 又这个线程去等待。

是这样吗?
unsigned long __stdcall foo(LPVOID param)
{
typedef struct{
HANDLE h;
SOCKET soc;
sockaddr *s;
int * inte;
SOCKET *returnsock;
}fo,*pfo;
pfo f = (fo*)param;
if(f!=NULL)
{
// do............

f->returnsock=(SOCKET *)accept(f->soc,f->s,f->inte);
}
delete f; // 这里删除
return 0;
}
SOCKET MyAccept( HWND hWnd,SOCKET sock,sockaddr *sa,int * inter)
{

typedef struct{
HANDLE h;
SOCKET soc;
sockaddr *s;
int * inte;
SOCKET *returnsock;
}fo,*pfo;
pfo f=new fo;
f->h=hWnd;
f->soc=sock;
f->s=sa;
f->inte=inter;
HANDLE tid = CreateThread( NULL, 0, foo, (LPVOID)f, 0, NULL );
if (!tid)
delete f;
else
::ResumeThread(tid);
CloseHandle(tid);

SOCKET newsock=(SOCKET)f->returnsock;
WaitForSingleObject( tid, INFINITE ); // 等待线程结束
return newsock;
}
wangxipu 2010-02-26
  • 打赏
  • 举报
回复
accpet是阻塞的,一个办法是另外再开一个线程专门处理它
另外一个办法是设置成非阻塞的模式
macrojj 2010-02-26
  • 打赏
  • 举报
回复
都让你不要在界面线程里面accpet了。
你开一个线程 又这个线程去等待。
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
引用 4 楼 macrojj 的回复:
不明白你的卡死是什么意思。
如果是完成端口的话。 你接受连接之后的workThread 没有时间片运行吗 ?
我理解的卡死是这个意思。 但是貌似不可能只在GUI程序有CUI里没有。 
你是说界面卡死了吧?

界面卡死了,有办法吗?
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
引用 3 楼 yangzhenping 的回复:
我用完成端口实现的,IOCP,求高手帮忙死循环问题

界面卡死了,有办法吗?
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
引用 7 楼 yangglemu 的回复:
另开线程去Accept

怎么开线程去Accept?
能给个函数看下吗?
  • 打赏
  • 举报
回复
另开线程去Accept
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
恩,对界面卡死了,所以不能在界面上做任何事了
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
不是while死循环问题,是accept()函数本身,无限循环查询新连接
macrojj 2010-02-26
  • 打赏
  • 举报
回复
不明白你的卡死是什么意思。
如果是完成端口的话。 你接受连接之后的workThread 没有时间片运行吗 ?
我理解的卡死是这个意思。 但是貌似不可能只在GUI程序有CUI里没有。
你是说界面卡死了吧?
yangzhenping 2010-02-26
  • 打赏
  • 举报
回复
我用完成端口实现的,IOCP,求高手帮忙死循环问题
  • 打赏
  • 举报
回复
在循环里Sleep(10)试试
hhh_hao 2010-02-26
  • 打赏
  • 举报
回复
用select模型吧, 无限循环,不能接受

64,281

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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