socket 接收线程实现(帖子)
来源:互联网 发布:多特vs希腊数据 编辑:程序博客网 时间:2024/05/16 18:09
我的服务程序在一个客户端接入以后就开一个接收线程,负责接收它的数据。
在此期间客户机保持和服务器的连接。
实际运行时,发现这个接收线程一运行,cpu利用率达到100%,根本接收不了其他的连接,请问大家怎么处理接收线程的?怎么改善接收线程的性能?
// 接收数据线程如下:
dword winapi recvthread(lpvoid lparam)
{
int socket;
socket= (int )lparam;
fd_set fdread;
struct timeval tmvtimeout={0l,100l};
char recvbuf[256];
while (true)
{
// 初始化
fd_zero(&fdread);
fd_set(socket,&fdread);
int ret = select(0,&fdread,null,null,&tmvtimeout);
if (ret == socket_error)
{
printf("select() socket error: %d../n",getlasterror ());
continue;
}
else if (ret > 0)
{
if (fd_isset(socket,&fdread))
{ // 有数据可读
nrecv= recv (socket, recvbuf, sizeof( recvbuf), 0);
if (nrecv == socket_error)
{ // 读数据出错
printf("recv socket error: %d../n",getlasterror());
}
else
if (nrecv == 0)
{ // 客户端断开连接
printf("remote socket closed../n");
closesocket(socket);
break;
}
// 数据读入成功,做数据处理
printf("successfully receive %d bytes../n"),nrecv);
processdata(recvbuf);
}
}
}
printf("recv thread exit with 0../n");
return 0;
}
我在串口通信中使用的是事件的触发方式,所以只有数据来的时候,才触发接收,
发表者:elusionsleep一下
发表者:wwwllg一种方法是加sleep(1).在while里面。
另一个方法是,是用事件方式。
你的接收处理方法有问题
if (ret == socket_error)
{
printf("select() socket error: %d../n",getlasterror ());
continue;//很显然,这里需要getlastererro看看一下错误原因,这样,在不需要的时候,跳出循环。
}
发表者:max_xy楼上的,请问怎么样处理select错误呢,按照您的意思。给点代码如何
发表者:truewq我也是用while实现的,不过我只是在监听网络,代码差不多你看一下嘛,刚开始我也是cpu占用很高,后来加了一个return 就好了:
dword winapi loopscanthread(lpvoid lpparam)
{
socket listensocket=(socket)lpparam;
sockaddr_in send;
int sendlen=sizeof(send);
cstring aa2="----接收方最大允许连接数为10----";
afxgetmainwnd()->sendmessagetodescendants(wm_listbox,(wparam)aa2.getbuffer(0),1);
aa2.releasebuffer();
//接收方允许最大的连结数是10
int rc=listen(listensocket,10);
if(rc==socket_error)
{
cstring a5="----创建监听socket失败,请检查网络后重试----";
afxgetmainwnd()->sendmessagetodescendants(wm_listbox,(wparam)a5.getbuffer(0),1);
a5.releasebuffer();
::messagebeep(mb_iconhand);
return 0;
}
cstring aa3="----创建监听socket成功,开始监听网络----";
afxgetmainwnd()->sendmessagetodescendants(wm_listbox,(wparam)aa3.getbuffer(0),1);
aa3.releasebuffer();
::messagebeep(mb_iconasterisk);
while(1)
{
socket connectsocket;
connectsocket=accept(listensocket,(sockaddr*)&send,&sendlen);
if(connectsocket==invalid_socket)
{
cstring a="----接收发送方请求失败----";
afxgetmainwnd()->sendmessagetodescendants(wm_listbox,(wparam)a.getbuffer(0),1);
a.releasebuffer();
::messagebeep(mb_iconhand);
return -1;
}
cstring a="----接收请求成功,连接已经建立----";
afxgetmainwnd()->sendmessagetodescendants(wm_listbox,(wparam)a.getbuffer(0),1);
a.releasebuffer();
//直到accept()成切返回,然后进入别一个线程,来接收文件消息
dword dwthread1;
::createthread(null,0,getfileinfothread,(lpvoid)connectsocket,0,&dwthread1);
}
return 0;
}发表者:max_xy刚刚觉得用settimer來做,不用while循环。不知道cpu会不会降低一点。来做个测试。
发表者:wwwllgbool cclientoverlappedsock::onread()
{
if(!isconnected())
return false;
dword dwtransbit = 0;
dword resv = 0;
dword dwflag = 0;
wsabuf buffer;
bool bquery = false;
int state = 0;
bquery = wsagetoverlappedresult( m_recsocket, &connectedsocketoverlapped,
&dwtransbit,false,&dwflag);
if(bquery)
{
if(dwtransbit == 0)
{
onclose();
return true;
}
while(1)
{
if( rpag.len - sizeof(pag) == datares)
{
////
work();
reset();
////
buffer.buf = (char*)& rpag;
buffer.len = sizeof(pag);
state = wsarecv( m_recsocket,&buffer,1,&resv,
&dwflag, &connectedsocketoverlapped,null);
if(state == 0)
{
continue;
}else
{
dword err = wsagetlasterror();
if(err != wsa_io_pending)
{
trace1("erro code1 %d/n",err);
onclose();
return false;
}else
{
if(error_io_pending == err)
{
return true;
}
}
}
}else
if( rpag.len - sizeof(pag) - datares > 0)
{
if(!m_breadpending)
{
if(buff == null)
{
buff = new char [ rpag.len - sizeof(pag)];
memset( buff,0, rpag.len - sizeof(pag));
buffer.buf = buff;
buffer.len = rpag.len - sizeof(pag);
}
resv = 0;
buffer.len = rpag.len - sizeof(pag) - datares;
buffer.buf = buff + datares;
state = wsarecv( m_recsocket,&buffer,1,&resv,
&dwflag, &connectedsocketoverlapped,null);
if(state == 0)
{
datares+=resv;
continue;
}else
{
dword err = wsagetlasterror();
if(err != wsa_io_pending)
{
trace1("erro code2 %d/n",err);
onclose();
return false;
}else
{
if(error_io_pending == err)
{
m_breadpending = true;
return true;
}
}
}
}else
{
datares+=dwtransbit;
}
}
if(!isconnected())
return 0;
sleep(1);
trace1("res data is %u/n",datares);
}
}else
{
dword err = wsagetlasterror();
if(err != error_io_incomplete)
{
onclose();
trace1("erro code3 %d/n",err);
return false;
}else
return true;
}
return true;
}
吐血回贴!
当没有数据来时,根本不占用cpu.
发表者:danscort2000加sleep控制
或者用消息event通知。
while
循环对cpu的消耗太巨大了,一定要有措施来主动交出cpu时间段
http://blog.csdn.net/metasearch/article/details/2148228
- socket 接收线程实现(帖子)
- socket 接收线程实现(帖子)
- 结束socket接收线程
- 普通接收函数的改进(时间片->线程实现)
- java socket实现文件的发送接收
- Udp同一个socket接收与发送实现
- socket实现http发送接收-<草稿>
- Java实现Socket发送和接收文件
- c# socket线程池实现
- java实现Socket通信(一)---单线程服务
- recv(经socket接收数据)
- Java Socket接收和发送(字符串)
- Java Socket接收和发送(字符串)
- Java Socket接收和发送(字符串)
- SOCKET实现广播(BoardCast)的发送和接收
- C#实现的可复用Socket接收/发送共享缓冲区类
- C#实现的可复用Socket接收/发送共享缓冲区类
- Java实现Socket发送和接收文件的代码
- 布局篇(1)
- Linux下shutdown命令详解
- MIDAS服务器程序包括:TDataSet;TProvider;TDatabase;TSession
- 虚析构函数(√)、纯虚析构函数(√)、虚构造函数(X)
- SCN what,why,how?
- socket 接收线程实现(帖子)
- asp 调用com+组件发送出现问题
- HIVE中join、semi join、outer join举例详解
- Linux中Shutdown命令使用介绍
- NDK Samples之two-libs
- 同样愚蠢的错误:关于C2533错误
- 对话框最小化到任务栏
- CSS3浏览器在线兼容查询工具 - Browser Support
- C# 清空数组