• 全部
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

微软的CSOCKET真是垃圾!!!!想知道原因的进来!!!

KingS_1 2002-05-11 05:35:53
屡试不爽!!!垃圾。。。
所以用socket,我有问题要问:希望你细心看完!我全部是一个字一个字打下!!

//////////////////////////////主机端//////////////////////////////////
//初始化//
socket();
bind();
listen();
accept();

//确认客户端连接后,开始阻塞接收//

//希望接收内容:从客户端连续接收recvedMsg1,recvedMsg2,recvedMsg3这3个数据//

//用途:此3个参数需要有序有长度的准确接收,用来做弹出MessageBox的参数//

//此3个参数接收完毕,马上弹出一个MessageBox//
MessageBox(recvedMsg1/*窗口内容*/,recvedMsg2/*窗口标题*/,
recvedMsg3/*按钮状态*/)


//////////////////////////////客户端///////////////////////////////////
//初始化
socket();
connect();

//连接成功后
String sendMsg1,sendMsg2;sendMsg3;
//然后将这3个数据按顺序正确的(每个数据的长度每次发送都不一样)传给服务端

//程序要求简洁明了,首先C/S建立连接,成功后,客户端按一下发送按钮便发送
//3个顺序作用始终相同的数据给主机;
//主机接收完成,并将这3个数据做为参数传给MessageBox弹出一个消息;
//接着又是下一次的客户端按件

//问题:1.数据顺序及每个数据的长度正确接收的问题;
// 2.考虑客户端连续按发送按钮的情况;
3.注意,send()发送的是数据流,在主机recv()的时候可能客户端3次连
续的发送会被主机一次接收的问题


/////////请将上面问题完整解决,帖出合理源码,或者说出你的看法即可//////////
...全文
17 点赞 收藏 20
写回复
20 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
ahao 2002-05-12
倒了,我看你先学点基础,别骂这骂那的
回复
hsengactive 2002-05-12
用CArchive
与你自己设置的一个struct,CSocket相配合使用!
回复
Richuen22 2002-05-12
问题: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)
让只连接一次。
回复
KingS_1 2002-05-11
我仍然在关注!!请大家继续说!!!!!!!


////////////////////////////关注///////////////////////////////////
///////////////////////////强烈关注////////////////////////////////
回复
KingS_1 2002-05-11
关键是怎么从这些字符串的位置读出来。。还有字符串长度的数据如何和BUF转换!!
回复
KingS_1 2002-05-11
请大家继续。我实在是对概念不是很了解。

麻烦得要命诶。继续继续。。。。。。。。

///////////////////继续说///我今天到明天早上一直关注/////关注/////

////////////////////////////关注////////////////////////////
回复
m_SuperIdler 2002-05-11
好象代码有点乱了,我解释一下,SOCKET在网络上的数据传输,是按流方式的,比如你发送的三个字符串,可能在一个或者两个数据包内可能就被发送了。而不是你想象中的3个数据包,你需要自己根据数据的长度(这个数据的长度可以附带在字符串的头信息中)手动分解这个数据包,我给你的这段代码就是实现这个功能的,你可以拷贝下来去试试
回复
wumugulu 2002-05-11
干脆让别人帮你都作了算了!!!!


msdn里面什么都有,主要你还得靠自己!
回复
m_SuperIdler 2002-05-11
兄弟,我没试,但我估计下面是你要的代码,这不是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);
}
}
}
回复
KingS_1 2002-05-11
关键是代码!字符串操作!

我骂CSOCKET是以为什么他都做了。
我基本上不知道我做了什么。

所以现在用SOCKET,对字符方面的操作,比如格式转换,字符串操作等不熟悉。

///////////////////关键是代码和相关必要函数//////////////////////
///////////////////////////请写出来//////////////////////////////
回复
wumugulu 2002-05-11
比如
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)转换回来再读它的值
回复
z_sky 2002-05-11
1、自己定义个应用包格式,包括:包头、包长度、3个msg段,这样你收包时就能分开了;
2、如果不是为没个msg定义个固定长的空间,你在每发送完一个msg串后,注意要记得发送一个char(0)来结束这个串,要不就都串在一起了;
3、CSocket虽然封装的有点小小问题,但还是比较好用的。还算不上垃圾吧。
回复
z_sky 2002-05-11
1、自己定义个应用包格式,包括:包头、包长度、3个msg段,这样你收包时就能分开了;
2、如果不是为没个msg定义个固定长的空间,你在每发送完一个msg串后,注意要记得发送一个char(0)来结束这个串,要不就都串在一起了;
3、CSocket虽然封装的有点小小问题,但还是比较好用的。还算不上垃圾吧。
回复
villastoner 2002-05-11
没有完美的。
按的你标准所有的软件全是垃圾。
回复
chen_jun_fen 2002-05-11
你用短连接,

在发送数据的时候用这样个模式
connect
send
close
connect
send
close
connect
send
close
每次发送数据都按照这样的模式
回复
KingS_1 2002-05-11
f_ky(毛蛋哥哥)
我就是用你的2种方法,第一种你怎么实现,主要字符串操作我不熟练,
所以经常出现类型转换的错误,请提供一个简单模型代码,然后写上必要的
字符操作函数。

第二种方法也一样,我是写一个DWORD在前面,但同样是字符与数组转换及操作的问题。同样请提供简单的模型代码和写上必要的字符串操作函数。

这里谁懂谁就写一下吧!!
回复
wumugulu 2002-05-11
这是当然了了,send只是发送到对方的接收缓冲区就正确返回了,而server端的recv只是从缓冲中读取数据,所以你说的三个msg连在一起的情况是不可避免的。

要解决,有两种办法:

1。发送的数据包定长,比如定为100,如果msg不够长,后面补上0x00,使每次send发送的长度为100,然后server端接受的最大长度也设为100,扔掉后面无用的就可以了(比较简单些)


2。只能自己来控制,比如每次发送的时候在msg的最前面加一个字节填写这个数据包的长度,然后再server端需要解析并拆分从缓冲得到的数据。(比较麻烦)
回复
Hover 2002-05-11
KingS_1 (King-=King Studio=-) 封装一个比MS的CSocket更好类给大家用如何??
回复
Hover 2002-05-11
..
回复
thehuns 2002-05-11
我惯用的方法,发送端每发一次数据,接受端给发送端反馈一个响应,发送端再发第二个数据包
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2002-05-11 05:35
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……