数据接受和发送,有意思的问题?大家请进,来者有分!

ISAKEEPER 2003-08-21 08:58:35
我的代码中既要传普通的数据又要传一些特殊的数据(如:数据传输的状况,是否正常还是需重发,以及定时的链路检测)。我目前的解决这个问题的思路是:在发送数据之前,先发送一个特殊的状态包,如在发送普通数据之前,先发送一个“N”,接着再发送普通数据;接收端:如果先接受到了“N”则转入接受普通数据的接受函数;其他的数据也类似。

客户端发送程序:
{
.......
CString string;
string = "N"; //“N”表示普通的数据
int end = sockClient.Send(string,string.GetLength());//特殊数据
int nSended = sockClient.Send(&protocol_send,sizeof(Protocol));//普通数据
.......
}
服务器端接受程序:
{
.......
int end = pSocket->Receive(flag,2);
dlg.m_type = flag[0];
CString temp;
temp = dlg.m_type;
AfxMessageBox(temp);//这里显示是 “N”

if (dlg.m_type =='N')
{
nReceived = pSocket->Receive(&protocol_rev,sizeof(Protocol));
......
}
........
}
结果服务端,接受显示的都是“00000000000000000000000”
没有没见到正常的数据,请高手指点!
...全文
63 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
ISAKEEPER 2003-08-23
  • 打赏
  • 举报
回复
我去试试
joinrry 2003-08-22
  • 打赏
  • 举报
回复
要睡觉啦,
明天仔细看吧!
feeboby 2003-08-22
  • 打赏
  • 举报
回复
sockClient.Send(string.GetBuffer(string.GetLength(),string.GetLength());//
lazycat818 2003-08-22
  • 打赏
  • 举报
回复
第一次接收到“N”时,下面一句Recieve接收的还是当前缓冲区的内容。而不是第二个Send的内容
第二次接收到数据,还是经过了是否N的判断,由于不是N,就没有接收后面的内容。

所以肯定是接收不到正确的内容的。

就是说,并不是主动去接收就能接收到下一个数据包,只是接收到当前数据包的下一个部分。
假如发送方发送了20个字节的数据,而接收方每次接收10个字节,那么第一个Recieve接收的是0-9,第二个Recieve接收的是10-19。
lazycat818 2003-08-22
  • 打赏
  • 举报
回复
我认为这种方法不好,应该自己定义消息格式,

char Buffer[MAX]//max为可能的最大值,CS两端一致
Buffer[0] = 'N';

memcpy(Buffer+1, &protocal, sizeof(protocal));

Socket.send(Buffer, MAX)//MAX可改为1+sizeof(protocal)

接收端:
在OnRecieve中处理:

char Buffer[MAX]//max为可能的最大值,CS两端一致

nReceived = pSocket->Receive(Buffer,MAX);

if(Buffer[0] == 'N')
{
Protocol protocal;
memcpy(&protocal, Buffer+1, sizeof(protocal));
}

示意代码,没有检测发送和接收的成败。

ISAKEEPER 2003-08-22
  • 打赏
  • 举报
回复
我延时2秒,仍然不行呀
叶子哟 2003-08-22
  • 打赏
  • 举报
回复
两次发之间延时一下
ISAKEEPER 2003-08-22
  • 打赏
  • 举报
回复
补充一下:
在客户端如果有两个发送数据的话,即
int end = sockClient.Send(string,string.GetLength());//特殊数据
int nSended = sockClient.Send(&protocol_send,sizeof(Protocol));//普通数据

服务器端的接受就不正常了

dlg.m_type 的数据很乱,dlg.m_type !='N'了。
ISAKEEPER 2003-08-22
  • 打赏
  • 举报
回复
TO tyzam(tyzam):你好!
我刚才做了两个试验:
1)如果把客户端的发送结构数据的语句(普通数据)注释掉

服务器端接受正常
int end = pSocket->Receive(flag,2);
//pSocket->Send(&protocol_send,sizeof(Protocol)); //该行注释掉
.......
AfxMessageBox()
if (dlg.m_type =='N')
{
AfxMessageBox("shu ju jieshou"); //该语句能够执行
.....
}

试验2:
把客户端、服务器端的特殊信息发送、接收都注释掉,
客户端发送程序:
{
.......
//CString string;
//string = "N"; //“N”表示普通的数据
//int end = sockClient.Send(string,string.GetLength());//特殊数据
int nSended = sockClient.Send(&protocol_send,sizeof(Protocol));//普通数据
.......
}
服务器端接受程序:
{
.......

// if (dlg.m_type =='N')
//{
nReceived = pSocket->Receive(&protocol_rev,sizeof(Protocol));
......
// }
........
}

只剩下普通数据,发送,接受数据都正常,

请大家帮我分析一下原因,谢谢!
tyzam 2003-08-22
  • 打赏
  • 举报
回复
这样接收是不行的
char buf[sizeof(Protocol)]="";
this->Receive(buf,sizeof(StrStudent));
protocol_rev=(struct Protocol*)buf;
呵呵我以前做socket程序时也是这样的不能直接接收结构体,只能先接收缓冲区的内容然后再按结构体的构架进行类型转换
MHB 2003-08-22
  • 打赏
  • 举报
回复
为什么要这样写????自定义自己的通讯包结构然后通过通讯包结构来确定通信中的数据不是很方便吗?
fanfyj 2003-08-22
  • 打赏
  • 举报
回复
up
mme 2003-08-22
  • 打赏
  • 举报
回复
你这样处理的方法是正确的,可是编程方面出了问题.
xiaoxx 2003-08-22
  • 打赏
  • 举报
回复
建议socket send recv都不要用字符串收发,容易出问题,因为CString在构造的时候,遇到'\0'就结束了,如果你的数据中含有这个就会出问题了。

用CByteArray不错,强烈推荐一把。

CByteArray arrByte;
arrByte.Setsize(int nByteYourNeeds);
//memcpy(arrByte.GetData() , (LPVOID)lpData , nByteYourNeeds);
socClient.Send(arrByte.GetData() , nByteYourNeeds)

Server端收数据的时候
要先将ByteArray设置大小,这个大小要固定为你所要收的数据的大小。
可以考虑在msg中含有固定大小的头部字段!

还有不少事情要做,UP
ISAKEEPER 2003-08-22
  • 打赏
  • 举报
回复

int end = pSocket->Receive(flag,2);
dlg.m_type = flag[0];
CString temp;
temp = dlg.m_type;
AfxMessageBox(temp);//这里显示是 “N”,这说明字符串的数据收到,且正确呀

现在我觉得是正常数据没有接受正常
nReceived = pSocket->Receive(&protocol_rev,sizeof(Protocol));接收的数据不对呀

另外,我想请教的是:如果采用这样的处理方式来接受不同类型的数据,是否可以呢?

ISAKEEPER 2003-08-21
  • 打赏
  • 举报
回复
UP

18,356

社区成员

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

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