===>使用setsockopt改变发送和接收的BUF,结果程序发送和接收受影响很大...

当我遇上-你 2011-11-25 11:37:35
我的服务器端使用的IOCP,客户端使用的选择模式,因为在客户端接收数据出现了接收一包数据部完整的情况,所以现在设置了发送和接收的缓冲区为0,结果导致每秒只有5个左右的数据包,没设置的时候每秒在1600个左右。 
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));
哪位朋友知道怎么回事呢?
...全文
209 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
当我遇上-你 2011-12-07
  • 打赏
  • 举报
回复
换了个方式实现了,但是问题还是解决...
先结贴吧,等高手
Yofoo 2011-11-28
  • 打赏
  • 举报
回复
IOCP 如果客户端接收的缓冲区为0, 服务器端将会一直等待客户端去接收, 导致服务器等待, 如果一个连接里面有多个包, 就可能会导致服务器阻塞(看设计情况), 这种情况服务器的效率是非常低的, 可能会出现LZ的情况

yynetsdk 2011-11-28
  • 打赏
  • 举报
回复

static bool DisableNagle(SOCKET pSock)
{
// 禁用Nagle算法
char bNagleValue = 1;
if(SOCKET_ERROR == setsockopt(pSock,IPPROTO_TCP,TCP_NODELAY,(char*)&bNagleValue,sizeof(bNagleValue)))
{
return false;
}
// 设置缓冲区
int nBufferSize = 0;//NET_BUFFER_SIZE;
if(SOCKET_ERROR == setsockopt(pSock,SOL_SOCKET,SO_SNDBUF,(char*)&nBufferSize,sizeof(nBufferSize)))
{
return false;
}
nBufferSize = 0;//NET_BUFFER_SIZE;
if(SOCKET_ERROR == setsockopt(pSock,SOL_SOCKET,SO_RCVBUF,(char*)&nBufferSize,sizeof(nBufferSize)))
{
return false;
}

nBufferSize = 0;
if(SOCKET_ERROR == setsockopt(pSock,SOL_SOCKET,SO_RCVTIMEO,(char*)&nBufferSize,sizeof(nBufferSize)))
{
return false;
}

if(SOCKET_ERROR == setsockopt(pSock,SOL_SOCKET,SO_SNDTIMEO,(char*)&nBufferSize,sizeof(nBufferSize)))
{
return false;
}

return true;
}

Eleven 2011-11-28
  • 打赏
  • 举报
回复
Nagle算法用于对缓冲区内的一定数量的消息进行自动连接。该处理过程(称为Nagling),通过减少必须发送的封包的数量,提高了网络应用 程序系统的效率。(Nagle虽然解决了小封包问题,但也导致了较高的不可预测的延迟,同时降低了吞吐量。)

vc下面socket编程,使用阻塞方式的时候,会自动使用Nagle算法,如:当pc不断发送32Bytes的数据的时候,会将这些包合并起来一起发送。如果另一头使用的时候一个tcp包一条命令处理的话,会出问题的。

在vc里,可以屏蔽掉该算法:

const char chOpt=1;
int nErr=setsockopt( m_socket, IPPROTO_TCP, TCP_NODELAY, &chOpt, sizeof(char));
if(nErr==-1)
{
TRACE(_T("setsockopt() error\n"),WSAGetLastError());
return ;
}

http://blog.csdn.net/yahohi/article/details/6717500
当我遇上-你 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 yynetsdk 的回复:]
C/C++ code

static bool DisableNagle(SOCKET pSock)
{
// 禁用Nagle算法
char bNagleValue = 1;
if(SOCKET_ERROR == setsockopt(pSock,IPPROTO_TCP,TCP_NO……
[/Quote]
在客户端和服务器端已经设置了 禁用Nagle算法
发送和接受的BUF设置为0,客户端使用的选择模式发送和接受,都是单独的线程
当我遇上-你 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 smwhotjay 的回复:]
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));

很重要.0 buff.就是把系统sock分配的缓冲区不用了.直接用你程序提供的buff.内核网络层会……
[/Quote]
那服务器端的完成端口,怎么没这问题呢?
smwhotjay 2011-11-25
  • 打赏
  • 举报
回复
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));
setsockopt(socket,SOL_S0CKET,SO_RCVBUF,(char *)&nZero,sizeof(int));


很重要.0 buff.就是把系统sock分配的缓冲区不用了.直接用你程序提供的buff.内核网络层会经常读取你程序的指定的sock buff内存.效率低.可想而知.
当我遇上-你 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 mxzy55560593 的回复:]
你应该禁用Nagle
[/Quote]
设置了禁用Nagle,跟没设置一样的效果...求解释
当我遇上-你 2011-11-25
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 brightlee 的回复:]
应该与这个Buffer关系不大吧!我以前也改大过,发现也不能多点之类的。
因为在客户端接收数据出现了接收一包数据不完整的情况!解决方法不是设置这个,而是把消息发送时,增加产学头部,直到读到相应在消息长度,才处理啊。
如Header部分为 WORD wID; //消息ID
char cFeather; //为一个检查字符
DWORD dwMsgLen; //消息内容的长度。
每次客户端收时……
[/Quote]
这个我知道,我的每个包的开始都有4字节的数据,表示发送的数据长度,现在我只想知道上面的问题为什么会这样?
mxzy55560593 2011-11-25
  • 打赏
  • 举报
回复
你应该禁用Nagle
brightLee 2011-11-25
  • 打赏
  • 举报
回复
应该与这个Buffer关系不大吧!我以前也改大过,发现也不能多点之类的。
因为在客户端接收数据出现了接收一包数据不完整的情况!解决方法不是设置这个,而是把消息发送时,增加产学头部,直到读到相应在消息长度,才处理啊。
如Header部分为 WORD wID; //消息ID
char cFeather; //为一个检查字符
DWORD dwMsgLen; //消息内容的长度。
每次客户端收时,先 Recv 7字节的头部,然后再根据头部 Recv相应的数据长度。完整后再处理。
如果Recv为0,表示同步读法的,对方断开连接。自己关闭Socket
当我遇上-你 2011-11-25
  • 打赏
  • 举报
回复
自己顶下,没人知道吗?

18,356

社区成员

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

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