微软的CSOCKET真是垃圾!!!!想知道原因的进来!!! KingS_1 (King-=King Studio=-) 封装一个比MS的CSocket更好类给大家用如何?? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 这是当然了了,send只是发送到对方的接收缓冲区就正确返回了,而server端的recv只是从缓冲中读取数据,所以你说的三个msg连在一起的情况是不可避免的。要解决,有两种办法:1。发送的数据包定长,比如定为100,如果msg不够长,后面补上0x00,使每次send发送的长度为100,然后server端接受的最大长度也设为100,扔掉后面无用的就可以了(比较简单些)2。只能自己来控制,比如每次发送的时候在msg的最前面加一个字节填写这个数据包的长度,然后再server端需要解析并拆分从缓冲得到的数据。(比较麻烦) f_ky(毛蛋哥哥)我就是用你的2种方法,第一种你怎么实现,主要字符串操作我不熟练,所以经常出现类型转换的错误,请提供一个简单模型代码,然后写上必要的字符操作函数。第二种方法也一样,我是写一个DWORD在前面,但同样是字符与数组转换及操作的问题。同样请提供简单的模型代码和写上必要的字符串操作函数。这里谁懂谁就写一下吧!! 你用短连接,在发送数据的时候用这样个模式connectsendcloseconnectsendcloseconnectsendclose每次发送数据都按照这样的模式 1、自己定义个应用包格式,包括:包头、包长度、3个msg段,这样你收包时就能分开了;2、如果不是为没个msg定义个固定长的空间,你在每发送完一个msg串后,注意要记得发送一个char(0)来结束这个串,要不就都串在一起了;3、CSocket虽然封装的有点小小问题,但还是比较好用的。还算不上垃圾吧。 1、自己定义个应用包格式,包括:包头、包长度、3个msg段,这样你收包时就能分开了;2、如果不是为没个msg定义个固定长的空间,你在每发送完一个msg串后,注意要记得发送一个char(0)来结束这个串,要不就都串在一起了;3、CSocket虽然封装的有点小小问题,但还是比较好用的。还算不上垃圾吧。 比如1。char temp[100];memset(temp, 0x00, sizeof(temp));strcpy(temp, msg1.GetBuffer(msg1.GetLength())); //CString msg1;int result = send(yoursocket, temp, sizeof(temp),0);2。复杂多了,DWORD是四字节的,发送的时候要用htonl(dword)转换长网络序接受端要用ntohl(dword)转换回来再读它的值 关键是代码!字符串操作!我骂CSOCKET是以为什么他都做了。我基本上不知道我做了什么。所以现在用SOCKET,对字符方面的操作,比如格式转换,字符串操作等不熟悉。///////////////////关键是代码和相关必要函数/////////////////////////////////////////////////请写出来////////////////////////////// 兄弟,我没试,但我估计下面是你要的代码,这不是MS的错,SOCKET是从UNIT下移植过来的,那边也是这么操作的,其实也不麻烦的:)void test(){ // 1 用TCP方式接收来自"数据服务器"的数据 int g_len; if ((g_len = recv(m_socketTCP, buf, 65536, 0)) == SOCKET_ERROR) {//gw3 ASSERTEX(FALSE); return; } else { g_saddr = 0; while (g_saddr < g_len) { if(addflag>0) { //上次有数据未全的处理 if(g_len>=addflag) { //这次可以补齐未全的数据 memcpy(&g_pBuf[g_addr],&buf[g_saddr],addflag); g_saddr+=addflag; addflag=0; } else { //这里如果还不够,则拷贝本次数据,并继续读取 memcpy(&g_pBuf[g_addr],buf,g_len); g_addr+=g_len; addflag-=g_len; return; } } else { //上次没有剩余数据,这里重新处理 g_addr=0; flag=*(WORD*)&buf[g_saddr]; switch(flag) { case 0x0C46: //F10 rlen=*(DWORD*)&buf[g_saddr+66]; break; case 0x0C45: rlen=*(DWORD*)&buf[g_saddr+66]; break; case 0x0C47: //股票代码表 rlen=*(DWORD*)&buf[g_saddr+6]; break; case 0x0D01: case 0x0D02: //申请的响应(非数据申请) rlen=33; break; case 0x0C48: //资讯文件表 rlen=*(DWORD*)&buf[g_saddr+6]; break; case 0x0C43: //补分笔数据 rlen=*(DWORD*)&buf[g_saddr+2]; break; case 0x0C44: //补日线数据 rlen=*(DWORD*)&buf[g_saddr+2]; break; case 0x0C41: //实时行情数据 rlen=*(DWORD*)&buf[g_saddr+2]; break; default: rlen=g_len-g_saddr; break; } if(rlen>(g_len-g_saddr)) { memcpy(g_pBuf,&buf[g_saddr],g_len-g_saddr); g_addr=g_len-g_saddr; addflag=rlen-(g_len-g_saddr); return; } else { memcpy(g_pBuf,&buf[g_saddr],rlen); g_saddr+=rlen; } } // 对接收到的数据进行处理 ASSERTEX(g_pBuf); ASSERTEX(rlen > 0); DoDataFromServerByTCP(g_pBuf, rlen); } }} 干脆让别人帮你都作了算了!!!!msdn里面什么都有,主要你还得靠自己! 好象代码有点乱了,我解释一下,SOCKET在网络上的数据传输,是按流方式的,比如你发送的三个字符串,可能在一个或者两个数据包内可能就被发送了。而不是你想象中的3个数据包,你需要自己根据数据的长度(这个数据的长度可以附带在字符串的头信息中)手动分解这个数据包,我给你的这段代码就是实现这个功能的,你可以拷贝下来去试试 关键是怎么从这些字符串的位置读出来。。还有字符串长度的数据如何和BUF转换!! 问题:1.数据顺序及每个数据的长度正确接收的问题;// 2.考虑客户端连续按发送按钮的情况; 3.注意,send()发送的是数据流,在主机recv()的时候可能客户端3次连 续的发送会被主机一次接收的问题我曾用CSocket编过,试一试吧:1:CSocket sockTemp; sockTemp.Create(18701,SOCK_STREAM, "127.0.0.1"); 即有连接的通信。 接着是关于数据稳定的问题。 主机端Send后,要用 如while(TRUE) { m_sockSend.Receive(pOK,4,0); if(*pOK==234598) Break; } 才可离开或接着Send,即确保客户方接收好了并发一个OK标志如234598才接着做。2:可用CButton:EnableWindows(FALSE)来屏蔽按钮3:sockTemp.Listen(1) 让只连接一次。 用CArchive与你自己设置的一个struct,CSocket相配合使用! 请教,如何把BYTE数组赋给CComBSTR? 加载对话框的问题! 请问编译速度为什么变慢 急需求助!需要一位高手帮助完成毕设!!! 急寻高手,关于多文档子窗口菜单的多语言切换问题,请见代码!在线 无限数值存储问题 在COM中,调用ADO时的返回值问题 vs2008 替换与查找 功能失效 重新问“vc下写软件发送短消息到手机的具体方法” 特征码定位输入偏移和机器码 特征码位置在哪里都可以 但是死掉了一直卡住 请教一个问题 各位,问个自己下载的问题。
2。只能自己来控制,比如每次发送的时候在msg的最前面加一个字节填写这个数据包的长度,然后再server端需要解析并拆分从缓冲得到的数据。(比较麻烦)
我就是用你的2种方法,第一种你怎么实现,主要字符串操作我不熟练,
所以经常出现类型转换的错误,请提供一个简单模型代码,然后写上必要的
字符操作函数。第二种方法也一样,我是写一个DWORD在前面,但同样是字符与数组转换及操作的问题。同样请提供简单的模型代码和写上必要的字符串操作函数。这里谁懂谁就写一下吧!!
connect
send
close
connect
send
close
connect
send
close
每次发送数据都按照这样的模式
2、如果不是为没个msg定义个固定长的空间,你在每发送完一个msg串后,注意要记得发送一个char(0)来结束这个串,要不就都串在一起了;
3、CSocket虽然封装的有点小小问题,但还是比较好用的。还算不上垃圾吧。
2、如果不是为没个msg定义个固定长的空间,你在每发送完一个msg串后,注意要记得发送一个char(0)来结束这个串,要不就都串在一起了;
3、CSocket虽然封装的有点小小问题,但还是比较好用的。还算不上垃圾吧。
1。
char temp[100];
memset(temp, 0x00, sizeof(temp));
strcpy(temp, msg1.GetBuffer(msg1.GetLength())); //CString msg1;
int result = send(yoursocket, temp, sizeof(temp),0);
2。
复杂多了,DWORD是四字节的,发送的时候要用htonl(dword)转换长网络序
接受端要用ntohl(dword)转换回来再读它的值
我基本上不知道我做了什么。所以现在用SOCKET,对字符方面的操作,比如格式转换,字符串操作等不熟悉。///////////////////关键是代码和相关必要函数//////////////////////
///////////////////////////请写出来//////////////////////////////
void test()
{
// 1 用TCP方式接收来自"数据服务器"的数据
int g_len; if ((g_len = recv(m_socketTCP, buf, 65536, 0)) == SOCKET_ERROR)
{//gw3
ASSERTEX(FALSE);
return;
}
else
{
g_saddr = 0;
while (g_saddr < g_len)
{
if(addflag>0)
{
//上次有数据未全的处理
if(g_len>=addflag)
{
//这次可以补齐未全的数据
memcpy(&g_pBuf[g_addr],&buf[g_saddr],addflag);
g_saddr+=addflag;
addflag=0;
}
else
{
//这里如果还不够,则拷贝本次数据,并继续读取
memcpy(&g_pBuf[g_addr],buf,g_len);
g_addr+=g_len;
addflag-=g_len;
return;
}
}
else
{
//上次没有剩余数据,这里重新处理
g_addr=0;
flag=*(WORD*)&buf[g_saddr];
switch(flag)
{
case 0x0C46: //F10
rlen=*(DWORD*)&buf[g_saddr+66];
break;
case 0x0C45:
rlen=*(DWORD*)&buf[g_saddr+66];
break;
case 0x0C47: //股票代码表
rlen=*(DWORD*)&buf[g_saddr+6];
break;
case 0x0D01:
case 0x0D02: //申请的响应(非数据申请)
rlen=33;
break;
case 0x0C48: //资讯文件表
rlen=*(DWORD*)&buf[g_saddr+6];
break;
case 0x0C43: //补分笔数据
rlen=*(DWORD*)&buf[g_saddr+2];
break;
case 0x0C44: //补日线数据
rlen=*(DWORD*)&buf[g_saddr+2];
break;
case 0x0C41: //实时行情数据
rlen=*(DWORD*)&buf[g_saddr+2];
break;
default:
rlen=g_len-g_saddr;
break;
}
if(rlen>(g_len-g_saddr))
{
memcpy(g_pBuf,&buf[g_saddr],g_len-g_saddr);
g_addr=g_len-g_saddr;
addflag=rlen-(g_len-g_saddr);
return;
}
else
{
memcpy(g_pBuf,&buf[g_saddr],rlen);
g_saddr+=rlen;
}
}
// 对接收到的数据进行处理
ASSERTEX(g_pBuf);
ASSERTEX(rlen > 0);
DoDataFromServerByTCP(g_pBuf, rlen);
}
}
}
msdn里面什么都有,主要你还得靠自己!
// 2.考虑客户端连续按发送按钮的情况;
3.注意,send()发送的是数据流,在主机recv()的时候可能客户端3次连
续的发送会被主机一次接收的问题
我曾用CSocket编过,试一试吧:
1:CSocket sockTemp;
sockTemp.Create(18701,SOCK_STREAM, "127.0.0.1");
即有连接的通信。
接着是关于数据稳定的问题。
主机端Send后,要用
如while(TRUE)
{
m_sockSend.Receive(pOK,4,0);
if(*pOK==234598)
Break;
}
才可离开或接着Send,即确保客户方接收好了并发一个OK标志如234598才接着做。
2:可用CButton:EnableWindows(FALSE)来屏蔽按钮
3:sockTemp.Listen(1)
让只连接一次。
与你自己设置的一个struct,CSocket相配合使用!