如何清空recv之后的socket缓冲区??

时间:2022-08-19 09:00:44
经过测试,socket的recv执行后,好似系统的缓冲区没有被及时清除,要等一会儿才会清除,各位是怎么自动清除里面的内容的(非自己定义的接收buffer),不知道怎么办,最好有源码

16 个解决方案

#1


一般都不处理这部分的,你为什么要这样做了

#2


引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??

#3


这个缓冲区不能清楚吧,它应该是跟SOCKET生存周期一致

你说的那个看见减少了内存肯定也不是SOCKET的缓冲区,是下层协议栈使用的内存吧

#4


引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。

#5


引用 4 楼 zhanshen2891 的回复:
引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。

现在的问题是,是采用的tcp协议,一个包头+包,包头为包的长度描述,
我在接受的时候,先读取包头,即取得包的长度,然后根据这个长度再读取多少字节的包,现在发现
有时候读取包头的时候,得到的长度不合理,都好几G了,我怀疑是里面有问题,但不知道问题出在哪里

#6


引用 5 楼 xiaopan 的回复:
引用 4 楼 zhanshen2891 的回复:
引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。

现在的问题是,是采……

有怀疑精神是好的,但是我要告诉你,这里就不用怀疑了,大家都这么用,都没什么问题,已经千锤百炼了,只能说明还你写的处理逻辑哪有问题。不知道你用的什么模型,我写了一个,服务端用的IOCP,客户端就是多线程的阻塞模型,5000个连接都一点问题没有。建议你再好好想想你的逻辑是不是哪里有漏洞。

#7


引用 6 楼 zhanshen2891 的回复:
引用 5 楼 xiaopan 的回复:
引用 4 楼 zhanshen2891 的回复:
引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你……

我只负责客户端,这边只需要打开recv即可,服务器采用的是push的方式,我对socket不是很精通,
不知道怎么样去检测现在的socket是否可用?恳请指点一下

#8


你应该把程序附上

#9



int CHttpSocket::GetDataLength()
{
if(!m_bConnected)
return 0;
  int nTotal = 0;

  char pDataFirst4[10];

  memset(pDataFirst4, 0, sizeof(pDataFirst4));

  int nRecLength = 0;

      struct timeval stWait;
      fd_set         stFdSet;
      int            lRet;
      
      stWait.tv_sec = 1;
      stWait.tv_usec = 0;

       FD_ZERO(&stFdSet);
       FD_SET(m_s, &stFdSet);
       lRet = select(FD_SETSIZE, &stFdSet, NULL, NULL, &stWait);
   switch(lRet)
   {
   case -1:
     return 0;
   break;
   case 0:
    return 0;
   break;
   default:
   if(FD_ISSET(m_s, &stFdSet))
   {
  nRecLength = recv(m_s, pDataFirst4, 4, 0);

  nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
   }
   break;
   }


return nTotal;

}

#10



BOOL CHttpSocket::Socket()
{
if(m_bConnected)
return FALSE;

struct protoent *ppe; 
 
WORD wVersionRequested = MAKEWORD( 2, 2 );
WSADATA wsaData;

wVersionRequested = MAKEWORD( 2, 2 );

if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
{
closesocket ( m_s ) ;
WSACleanup () ;
MessageBox(NULL, "socket()函数执行失败!", "错误", MB_OK);
return FALSE ;
}
ppe=getprotobyname("TCP");//getprotobynumber(6);//

///创建SOCKET对象
m_s=socket(PF_INET,SOCK_STREAM, ppe->p_proto);

BOOL   bKeepAlive   =   TRUE; 

int nRet;
  
int nRecvBuf = 16*1024;//设置为16k
nRet = setsockopt(m_s, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
if   (nRet   !=0) 

return FALSE;

  
if(m_s==INVALID_SOCKET)
{
MessageBox(NULL, "socket()函数执行失败!", "错误", MB_OK);
return FALSE;
}
return TRUE;

}

#11


  nRecLength = recv(m_s, pDataFirst4, 4, 0);

   nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);

nTotal 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?

#12


引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??

你Debug下调试一下

#13


引用 11 楼 shn521 的回复:
nRecLength = recv(m_s, pDataFirst4, 4, 0);

  nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);

nTotal 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?

因为这个是bcd码来的,每一位代表一个数字

#14


nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
应该是pDataFirst4[0]+ (pDataFirst4[1] *10) + (pDataFirst4[2] *100) + (pDataFirst4[3] *1000);这样吧

#15


nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
这里肯定有问题啦,
char本身就8位,左移8、16、24位就变成0或0xFF了

看样子貌似是字节序转换
nTotal = *(int*)pDataFirst4;
nTotal = ntohl(nTotal);

#16


引用 15 楼 stjay 的回复:
nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
这里肯定有问题啦,
char本身就8位,左移8、16、24位就变成0或0xFF了

看样子貌似是字节序转换
nTotal = *(int*)pDataFirst4;
nTotal = nto……


我改成byte类型的,好似可以了,呵呵,再测试一下,看看如何

#1


一般都不处理这部分的,你为什么要这样做了

#2


引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??

#3


这个缓冲区不能清楚吧,它应该是跟SOCKET生存周期一致

你说的那个看见减少了内存肯定也不是SOCKET的缓冲区,是下层协议栈使用的内存吧

#4


引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。

#5


引用 4 楼 zhanshen2891 的回复:
引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。

现在的问题是,是采用的tcp协议,一个包头+包,包头为包的长度描述,
我在接受的时候,先读取包头,即取得包的长度,然后根据这个长度再读取多少字节的包,现在发现
有时候读取包头的时候,得到的长度不合理,都好几G了,我怀疑是里面有问题,但不知道问题出在哪里

#6


引用 5 楼 xiaopan 的回复:
引用 4 楼 zhanshen2891 的回复:
引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。

现在的问题是,是采……

有怀疑精神是好的,但是我要告诉你,这里就不用怀疑了,大家都这么用,都没什么问题,已经千锤百炼了,只能说明还你写的处理逻辑哪有问题。不知道你用的什么模型,我写了一个,服务端用的IOCP,客户端就是多线程的阻塞模型,5000个连接都一点问题没有。建议你再好好想想你的逻辑是不是哪里有漏洞。

#7


引用 6 楼 zhanshen2891 的回复:
引用 5 楼 xiaopan 的回复:
引用 4 楼 zhanshen2891 的回复:
引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??


收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你……

我只负责客户端,这边只需要打开recv即可,服务器采用的是push的方式,我对socket不是很精通,
不知道怎么样去检测现在的socket是否可用?恳请指点一下

#8


你应该把程序附上

#9



int CHttpSocket::GetDataLength()
{
if(!m_bConnected)
return 0;
  int nTotal = 0;

  char pDataFirst4[10];

  memset(pDataFirst4, 0, sizeof(pDataFirst4));

  int nRecLength = 0;

      struct timeval stWait;
      fd_set         stFdSet;
      int            lRet;
      
      stWait.tv_sec = 1;
      stWait.tv_usec = 0;

       FD_ZERO(&stFdSet);
       FD_SET(m_s, &stFdSet);
       lRet = select(FD_SETSIZE, &stFdSet, NULL, NULL, &stWait);
   switch(lRet)
   {
   case -1:
     return 0;
   break;
   case 0:
    return 0;
   break;
   default:
   if(FD_ISSET(m_s, &stFdSet))
   {
  nRecLength = recv(m_s, pDataFirst4, 4, 0);

  nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
   }
   break;
   }


return nTotal;

}

#10



BOOL CHttpSocket::Socket()
{
if(m_bConnected)
return FALSE;

struct protoent *ppe; 
 
WORD wVersionRequested = MAKEWORD( 2, 2 );
WSADATA wsaData;

wVersionRequested = MAKEWORD( 2, 2 );

if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
{
closesocket ( m_s ) ;
WSACleanup () ;
MessageBox(NULL, "socket()函数执行失败!", "错误", MB_OK);
return FALSE ;
}
ppe=getprotobyname("TCP");//getprotobynumber(6);//

///创建SOCKET对象
m_s=socket(PF_INET,SOCK_STREAM, ppe->p_proto);

BOOL   bKeepAlive   =   TRUE; 

int nRet;
  
int nRecvBuf = 16*1024;//设置为16k
nRet = setsockopt(m_s, SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBuf, sizeof(int));
if   (nRet   !=0) 

return FALSE;

  
if(m_s==INVALID_SOCKET)
{
MessageBox(NULL, "socket()函数执行失败!", "错误", MB_OK);
return FALSE;
}
return TRUE;

}

#11


  nRecLength = recv(m_s, pDataFirst4, 4, 0);

   nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);

nTotal 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?

#12


引用 2 楼 xiaopan 的回复:
引用 1 楼 fishion 的回复:
一般都不处理这部分的,你为什么要这样做了

现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??

你Debug下调试一下

#13


引用 11 楼 shn521 的回复:
nRecLength = recv(m_s, pDataFirst4, 4, 0);

  nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);

nTotal 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?

因为这个是bcd码来的,每一位代表一个数字

#14


nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
应该是pDataFirst4[0]+ (pDataFirst4[1] *10) + (pDataFirst4[2] *100) + (pDataFirst4[3] *1000);这样吧

#15


nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
这里肯定有问题啦,
char本身就8位,左移8、16、24位就变成0或0xFF了

看样子貌似是字节序转换
nTotal = *(int*)pDataFirst4;
nTotal = ntohl(nTotal);

#16


引用 15 楼 stjay 的回复:
nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
这里肯定有问题啦,
char本身就8位,左移8、16、24位就变成0或0xFF了

看样子貌似是字节序转换
nTotal = *(int*)pDataFirst4;
nTotal = nto……


我改成byte类型的,好似可以了,呵呵,再测试一下,看看如何