16 个解决方案
#1
一般都不处理这部分的,你为什么要这样做了
#2
现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??
#3
这个缓冲区不能清楚吧,它应该是跟SOCKET生存周期一致
你说的那个看见减少了内存肯定也不是SOCKET的缓冲区,是下层协议栈使用的内存吧
你说的那个看见减少了内存肯定也不是SOCKET的缓冲区,是下层协议栈使用的内存吧
#4
收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。
#5
现在的问题是,是采用的tcp协议,一个包头+包,包头为包的长度描述,
我在接受的时候,先读取包头,即取得包的长度,然后根据这个长度再读取多少字节的包,现在发现
有时候读取包头的时候,得到的长度不合理,都好几G了,我怀疑是里面有问题,但不知道问题出在哪里
#6
有怀疑精神是好的,但是我要告诉你,这里就不用怀疑了,大家都这么用,都没什么问题,已经千锤百炼了,只能说明还你写的处理逻辑哪有问题。不知道你用的什么模型,我写了一个,服务端用的IOCP,客户端就是多线程的阻塞模型,5000个连接都一点问题没有。建议你再好好想想你的逻辑是不是哪里有漏洞。
#7
我只负责客户端,这边只需要打开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 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?
nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
nTotal 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?
#12
你Debug下调试一下
#13
因为这个是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);这样吧
应该是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);
这里肯定有问题啦,
char本身就8位,左移8、16、24位就变成0或0xFF了
看样子貌似是字节序转换
nTotal = *(int*)pDataFirst4;
nTotal = ntohl(nTotal);
#16
我改成byte类型的,好似可以了,呵呵,再测试一下,看看如何
#1
一般都不处理这部分的,你为什么要这样做了
#2
现在收到乱码,我怀疑是这个原因。
是否每次recv之前,都需要检测一下socket的状态??
#3
这个缓冲区不能清楚吧,它应该是跟SOCKET生存周期一致
你说的那个看见减少了内存肯定也不是SOCKET的缓冲区,是下层协议栈使用的内存吧
你说的那个看见减少了内存肯定也不是SOCKET的缓冲区,是下层协议栈使用的内存吧
#4
收到乱码??使用的TCP么?我想你没有明白TCP为什么叫流式协议。你需要自己拆包的。
#5
现在的问题是,是采用的tcp协议,一个包头+包,包头为包的长度描述,
我在接受的时候,先读取包头,即取得包的长度,然后根据这个长度再读取多少字节的包,现在发现
有时候读取包头的时候,得到的长度不合理,都好几G了,我怀疑是里面有问题,但不知道问题出在哪里
#6
有怀疑精神是好的,但是我要告诉你,这里就不用怀疑了,大家都这么用,都没什么问题,已经千锤百炼了,只能说明还你写的处理逻辑哪有问题。不知道你用的什么模型,我写了一个,服务端用的IOCP,客户端就是多线程的阻塞模型,5000个连接都一点问题没有。建议你再好好想想你的逻辑是不是哪里有漏洞。
#7
我只负责客户端,这边只需要打开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 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?
nTotal = pDataFirst4[0] + (pDataFirst4[1] << 8) + (pDataFirst4[2] << 16) + (pDataFirst4[3] << 24);
nTotal 应该是数据大小吗? 这个包头是怎么定义格式的?怎么接收端还要移位?
#12
你Debug下调试一下
#13
因为这个是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);这样吧
应该是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);
这里肯定有问题啦,
char本身就8位,左移8、16、24位就变成0或0xFF了
看样子貌似是字节序转换
nTotal = *(int*)pDataFirst4;
nTotal = ntohl(nTotal);
#16
我改成byte类型的,好似可以了,呵呵,再测试一下,看看如何