CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  基础类

紧急:有关SOCKET程序如何将数据打包?

楼主axin_online(阿新在线)2002-03-29 11:24:53 在 VC/MFC / 基础类 提问

数据包格式要求如下:  
      字节长度         内容  
            1                 起始符,为0xFE  
            2                 包体长度  
            16               手机号码  
            n                 包体(字符串)  
  如何将(例如:手机号码:13012345678,包体:ABCDE)打包发出?  
  str系列操作中'\0'很是麻烦,高手指点,不胜感谢!!!!! 问题点数:20、回复次数:32Top

1 楼snsins(初雪草)回复于 2002-03-29 11:35:59 得分 0

采用一个特定的自己的格式可以吗??比如  
   
  0xFE|5|13012345678|ABCDE|  
   
  Top

2 楼ququshb(忘求了)回复于 2002-03-29 11:38:11 得分 0

定义一个结构:  
  typedef   struct   _packet  
  {  
        char   id;  
        int   iIength;  
        char   cPhone[16];  
        char   cBody[255];  
  }packet;  
  packet   m_packet;  
  ZeroMemory(&m_packet,sizeof(packet));  
  m_packet.id   =   0xfe;  
  m_packet.iIength   =   1+4+16+255;  
  CopyMemory(m_packet.cPhone,"13012345678",11);  
  CopyMemory(m_packet.cBody,"ABCDE",5);  
  发出  
   
  Top

3 楼axin_online(阿新在线)回复于 2002-03-29 13:32:44 得分 0

我试了一下楼上的,但对方还是不能得到正确结果?  
  是用socket.Send(&m_packet,m_packet.iLength);  
  不知怎么回事?Top

4 楼greenyard(greenyard)回复于 2002-03-29 14:00:02 得分 0

应该是socket.Send(&m_packet,sizeof(packet));Top

5 楼dash()回复于 2002-03-29 14:02:22 得分 0

你是用的tcp吧?try   it:  
  int   sended;  
  while(sended<sizeof(packet))  
  {  
          sended+=send(s,....)  
  }  
   
  接收方也同Top

6 楼florist2000(我爱susan)回复于 2002-03-29 14:03:10 得分 0

修改一下  
   
   
  定义一个结构:  
  typedef   struct   _packet  
  {  
        char   id;  
        int   iIength;  
        char   cPhone[16];  
        char   cBody[255];  
  }packet;  
  packet   m_packet;  
  ZeroMemory(&m_packet,sizeof(packet));  
  m_packet.id   =   0xfe;  
   
  m_packet.iIength   =   1+4+16+255;//这句有错误,呵呵  
  m_packet.iLength=sizeof   (m_packet)//因为第一个是char型的数据不是一个字节,存在字节对齐问题。  
   
  CopyMemory(m_packet.cPhone,"13012345678",11);  
  CopyMemory(m_packet.cBody,"ABCDE",5);  
  发出  
   
  socket.Send(&m_packet,sizeof(m_packet));  
  另外如果使用的是阻塞型套节字,那么发出的字节数不一定就刚好是数据长度。  
  Top

7 楼lianhuiyong(阳关故人)回复于 2002-03-29 14:03:11 得分 0

ququshb(忘求了)   说得不错,这种方法应该没有错的,在接收端采用同样的结构体就可以了.Top

8 楼axin_online(阿新在线)回复于 2002-03-29 14:36:41 得分 0

1)我使用的阻塞型套节字,多线程.  
  2)对端不可能也采用这样的结构.  
  3)协议中规定起始符为一字节,长度为2字节,那么在Win2000和Win98中实现  
  该结构有何区别?一字节我觉得应该用BYTE?  
  4)接收端使用*((Short)包头+偏移值)来求包体长度不知对否?  
   
  另,我有好多头疼的问题,哪位专家能否在QQ中详聊,我的QQ   是   95896000.Top

9 楼axin_online(阿新在线)回复于 2002-03-29 15:02:48 得分 0

对端的接收线程,请大虾指点迷津:  
  UINT   RecvThread(LPVOID   pParam)  
  {  
  RECVDATA   *pRecv=(RECVDATA   *)pParam;  
   
  int   len=1;  
  int   error=0;  
  char   *pBody=NULL;  
  char   *pHdr=NULL;  
  char   tmp1[255];  
  char   tmp2[1024];  
  while   (TRUE)  
  {  
  int   res;  
   
  pBody=NULL;  
  pHdr=new   char[pRecv->hdrSz];  
  if   ((res=pRecv->pSocket->CAsyncSocket::Receive(pHdr,   pRecv->hdrSz))==SOCKET_ERROR)  
  error=::GetLastError();  
  else  
  len=res;  
   
  if   (len==0   ||   error==WSAECONNRESET   ||   error==WSAECONNABORTED)   break;  
   
  if   (!error   &&   len   &&   pRecv->bodyPos!=-1)  
  {  
  short   bodyLen=*((short   *)pHdr+pRecv->bodyPos);  
  pBody=new   char[bodyLen];  
   
  if   ((res=pRecv->pSocket->CAsyncSocket::Receive(pBody,bodyLen))==SOCKET_ERROR)  
  error=::GetLastError();  
  else  
  len+=res;  
   
  if   (len==0   ||   error==WSAECONNRESET   ||   error==WSAECONNABORTED)   break;  
  }  
   
  pRecv->pQueue->Add(new   CMyMsg(pHdr,pBody,len,error));  
   
  pRecv->pWnd->PostMessage(WM_NEW_MESSAGE);  
   
  }  
   
  //清理,防止内存泄露  
  delete   []pHdr;  
  delete   []pBody;  
   
  pRecv->pWnd->SendMessage(WM_DONE_MESSAGE,(WPARAM)pRecv->id,(LPARAM)error);  
   
  return   0;  
  }  
  Top

10 楼niewq(强强)回复于 2002-03-29 15:32:31 得分 0

你保证给分我给你指点。上述都不能解决你的问题!Top

11 楼niewq(强强)回复于 2002-03-29 15:36:03 得分 0

对端的接收线程就像儿童级程序!  
  Top

12 楼axin_online(阿新在线)回复于 2002-03-29 15:45:22 得分 0

请指教!我保证给分,不够在加.Top

13 楼niewq(强强)回复于 2002-03-29 16:20:51 得分 0

1、需要考虑断链重连。  
  2、接收端收到的包不可能都是完整包!处理方法,开一个缓冲区,有数据来就接在缓冲区后面,然后来判断数据包。  
  3、最好是Client端在出现断链后发起重连。Server端在一个连接断开后,接受新的连接。  
  4、结构定义{包头标志,固定字段等,消息长度,消息(不定长度)}  
  如果还搞不定,留下email地址!Top

14 楼axin_online(阿新在线)回复于 2002-03-29 16:33:02 得分 0

我主要想知道怎样将数据打包,发送至对方,  
  不知上面说的结构有没有问题?  
  因为要处理UniCode和MBCS及不同操作系统之间,还有字节顺序等,这是重点  
  至于断链重连,错误捕获等已实现,不便写出,就不必深究了.Top

15 楼devil97518(天使也会疯)回复于 2002-03-29 16:53:03 得分 20

一定要自己定义数据结构,基于c/s的两边数据结构都得相同,上述几位说得不错,我给你一个超时处理方法,注意两边的数据结构要相同,很简单的。  
  我是基于c++左的,,你可以参考,改为mfc的形式。  
  WSADATA   wsd;  
  SOCKET   cClient;  
  int   ret;  
  struct   sockaddr_in   server;  
  hostent   *host=NULL;  
   
  if(WSAStartup(MAKEWORD(2,0),&wsd)){return   0;}  
  cClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  if(cClient==INVALID_SOCKET){return   0;}  
  //set   Recv   and   Send   time   out  
  int   TimeOut=6000;   //设置发送超时6秒  
  if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char   *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){  
  return   0;  
  }  
  TimeOut=6000;//设置接收超时6秒  
  if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char   *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){  
  return   0;  
  }  
  //设置非阻塞方式连接  
  unsigned   long   ul   =   1;  
  ret   =   ioctlsocket(cClient,   FIONBIO,   (unsigned   long*)&ul);  
  if(ret==SOCKET_ERROR)return   0;  
   
  //连接  
  server.sin_family   =   AF_INET;  
  server.sin_port   =   htons(25);  
  server.sin_addr   .s_addr   =   inet_addr((LPCSTR)pSmtp);  
  if(server.sin_addr.s_addr   ==   INADDR_NONE){return   0;}  
   
  connect(cClient,(const   struct   sockaddr   *)&server,sizeof(server));  
   
  //select   模型,即设置超时  
  struct   timeval   timeout   ;  
  fd_set   r;  
   
  FD_ZERO(&r);  
  FD_SET(cClient,   &r);  
  timeout.tv_sec   =   15;   //连接超时15秒  
  timeout.tv_usec   =0;  
  ret   =   select(0,   0,   &r,   0,   &timeout);  
  if   (   ret   <=   0   )  
  {  
  ::closesocket(cClient);  
  return   0;  
  }  
  //一般非锁定模式套接比较难控制,可以根据实际情况考虑   再设回阻塞模式  
  unsigned   long   ul1=   0   ;  
  ret   =   ioctlsocket(cClient,   FIONBIO,   (unsigned   long*)&ul1);  
  if(ret==SOCKET_ERROR){  
  ::closesocket   (cClient);  
  return   0;  
  }Top

16 楼niewq(强强)回复于 2002-03-29 16:55:53 得分 0

那不要用结构了,以字节为单位,开始几个字节(例如8个等)意义定义,在8个字节里面,说明后面数据的长度,接收端在收到后,怎么处理都行。Top

17 楼niewq(强强)回复于 2002-03-29 16:59:05 得分 0

很容易啊,自己试一下就都知道了嘛!Top

18 楼axin_online(阿新在线)回复于 2002-03-29 17:12:27 得分 0

强强:用结构做发送出去的字节序列和你说的方法是一样的,哪个更方便呢?  
  天使也会疯:谢谢!但在Win2000(UniCode)下如何设定一个字节呢?Top

19 楼niewq(强强)回复于 2002-03-30 09:16:03 得分 0

不要用结构,用结构的兼容性差,而且一旦出错将是崩溃型的。用字节来处理!即使有错,则错一、二条消息而已。Top

20 楼niewq(强强)回复于 2002-03-30 09:24:17 得分 0

建议所有字节都用两个字节来表示,在非Unicode的地方与Unicode的地方处理不同就行了!Top

21 楼kissfire(kissfire)回复于 2002-03-30 13:13:42 得分 0

signTop

22 楼dxhdxh2k(dxhdxh)回复于 2002-03-31 08:55:35 得分 0

upTop

23 楼iiii(甲天下汤圆)回复于 2002-03-31 20:54:01 得分 0

upTop

24 楼axin_online(阿新在线)回复于 2002-04-01 09:29:31 得分 0

各位继续发表高见Top

25 楼maxsuy(魔法兔子)回复于 2002-04-01 10:07:07 得分 0

我觉得你的程序存在相当大的资源浪费  
  如果数据体只有一个字节,也要发送300个字节的数据?  
  我的QQ525931,  
  EMAIL,cnredmay@163.comTop

26 楼axin_online(阿新在线)回复于 2002-04-01 10:22:46 得分 0

发送问题很好解决,定义该结构,但发送字节数按实际填写Top

27 楼it_wsp(挖掘者)回复于 2002-04-01 11:43:01 得分 0

很好的问题,我来倾听大家的高见了!  
  Top

28 楼knl(小K)回复于 2002-04-01 11:57:19 得分 0

真实高见!Top

29 楼Ask100()回复于 2002-04-01 23:44:26 得分 0

关注Top

30 楼daryl715(上善若水)回复于 2002-04-02 00:03:21 得分 0

关注Top

31 楼Developerljm(飞车)回复于 2002-04-02 17:01:19 得分 0

一群疯子,这么简单、简单的问题,用得着这么大动干戈吗???Top

32 楼jet_u()回复于 2002-04-02 17:06:27 得分 0

跟我遇到的问题有相似处Top

33 楼snsins(初雪草)回复于 2002-04-02 18:01:55 得分 0

根本就不要用到字节和结构!  
  其实很简单的问题  
   
  就按照我开始说的   那样,采用|来分割,以|结束一个包  
   
  收到后只要按照|来分解包就OK了  
   
  0xFE|5|13012345678|ABCDE|  
  Top

相关问题

  • 紧急,有关程序打包的问题
  • 紧急求救应用程——序打包发布问题!
  • 紧急求救,关于installshield6.22打包有数据库的程序!
  • 程序打包
  • 程序打包?
  • 关于程序打包的问题?紧急万分!百分感谢!
  • 紧急求助关于应用程序打包ORACLE客户端的问题?
  • VB程序打包?
  • ADO程序打包
  • 求打包程序

关键词

  • socket
  • 数据
  • 数据结构
  • 连接
  • 结构
  • precv
  • cclient
  • 超时
  • packet
  • bodylen

得分解答快速导航

  • 帖主:axin_online
  • devil97518

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo