找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 3624|回复: 9

请教如何发送和接收struct结构?

[复制链接]
发表于 2008-5-14 10:16:10 | 显示全部楼层 |阅读模式
比如,我的客户端有一个消息为:
struct MSG
{
      int id;
      char name[10];
};

我应该如何把这一个struct消息发送给服务端呢?而服务端接收后也可以以同样一个struct来保存所接收到的数据?
请教大虾们 connect和acceptor 应该做哪些工作,如何做以及应注意的要点是什么??
发表于 2008-5-14 15:56:49 | 显示全部楼层
TCP网络传输是流,只认字节流,不认结构的。
所以即使你可以从字节流中重建出结构 - 很简单,直接按结构体读进去,但可能遇到字节不足、跨越边界的情况,必须谨慎。
发表于 2008-5-14 15:57:04 | 显示全部楼层
和connect / acceptor没什么关系
发表于 2008-11-18 17:08:35 | 显示全部楼层
我也遇到同样的问题,原来服务端和客户端都是用TCPSOCKET编写的,现在服务端想用ACE编写(移植到LINUX上)处理客户端发来的STUCT,不知道如何处理,比较麻烦的事情,希望知晓的老大摆脱指点迷经,给个简短的代码都可以!这里先写过

typedef struct _User              //用户信息
{
int      id;
char     name[32];
char     password[255];
char     question[255];
char     result[255];
}User;

就是想让ACE处理这个struct,然后发送下面的数据包标识,很是麻烦嗷

typedef enum _FLAG              //数据包的标记
{
    LOGIN,
LOGINFAULT,
LOGINSUCCESS
}FLAG;

想找处理这个方面的源码都找不到。两天了,累死了!!

[ 本帖最后由 marry 于 2008-11-18 17:16 编辑 ]
发表于 2008-11-18 17:09:46 | 显示全部楼层
我随时关注,等待好人的降临!
发表于 2008-11-18 17:42:59 | 显示全部楼层
这有何难啊,拼数据呀。

看看ACE的例子:
void AIO_Input_Handler::handle_read_stream
    (const ACE_Asynch_Read_Stream::Result &result) {
  if (!result.success () || result.bytes_transferred () == 0)
    delete this;
  else if (result.bytes_transferred () < result.bytes_to_read ())
    reader_.read (*mblk_, result.bytes_to_read () -
                  result.bytes_transferred ());
  else if (mblk_->length () == LOG_HEADER_SIZE) {
    ACE_InputCDR cdr (mblk_);

    ACE_CDR::Boolean byte_order;
    cdr >> ACE_InputCDR::to_boolean (byte_order);
    cdr.reset_byte_order (byte_order);

    ACE_CDR::ULong length;
    cdr >> length;

    mblk_->size (length + LOG_HEADER_SIZE);
    reader_.read (*mblk_, length);
  }
  else {
    if (OUTPUT_HANDLER::instance ()->put (mblk_) == -1)
      mblk_->release ();

    ACE_NEW_NORETURN
      (mblk_, ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE));
    ACE_CDR::mb_align (mblk_);
    reader_.read (*mblk_, LOG_HEADER_SIZE);
  }
}
其他的也有:
int Logging_Handler::recv_log_record (ACE_Message_Block *&mblk)
{
  // Put <logging_peer>'s hostname in new message block.
  ACE_INET_Addr peer_addr;
  logging_peer_.get_remote_addr (peer_addr);
  mblk = new ACE_Message_Block (MAXHOSTNAMELEN + 1);
  peer_addr.get_host_name (mblk->wr_ptr (), MAXHOSTNAMELEN);
  mblk->wr_ptr (ACE_OS::strlen (mblk->wr_ptr ()) + 1); // Go past name

  // Allocate a message block for the payload; initially at least
  // large enough to hold the header, but needs some room for
  // alignment.
  ACE_Message_Block *payload =
    new ACE_Message_Block (ACE_DEFAULT_CDR_BUFSIZE);
  // Align the Message Block for a CDR stream
  ACE_CDR::mb_align (payload);
  if (logging_peer_.recv_n (payload->wr_ptr (), 8) == 8) {
    payload->wr_ptr (8);               // Reflect addition of 8 bytes

    // Create a CDR stream to parse the 8-byte header.
    ACE_InputCDR cdr (payload);

    // Extract the byte-order and use helper methods to
    // disambiguate octet, booleans, and chars.
    ACE_CDR::Boolean byte_order;
    cdr >> ACE_InputCDR::to_boolean (byte_order);

    // Set the byte-order on the stream...
    cdr.reset_byte_order (byte_order);

    // Extract the length
    ACE_CDR::ULong length;
    cdr >> length;

    // Ensure there's sufficient room for log record payload.
    ACE_CDR::grow (payload, 8 + ACE_CDR::MAX_ALIGNMENT + length);

    // Use <recv_n> to obtain the contents.
    if (logging_peer_.recv_n (payload->wr_ptr (), length) > 0) {
      payload->wr_ptr (length);   // Reflect additional bytes
      // Chain the payload to mblk via the contination field.
      mblk->cont (payload);
      return length;
    }
  }
  // Error cases end up here, so we need to release the memory to
  // prevent a leak.
  payload->release ();
  payload = 0;
  mblk->release ();
  mblk = 0;
  return -1;
}


int Logging_Handler::write_log_record (ACE_Message_Block *mblk)
{
  // Peer hostname is in the <mblk> and the log record data
  // is in its continuation.
  if (log_file_->send_n (mblk) == -1)
    return -1;
  if (ACE::debug ()) {
    // Build a CDR stream from the log record data.
    ACE_InputCDR cdr (mblk->cont ());
    ACE_CDR::Boolean byte_order;
    ACE_CDR::ULong length;
    // Extract the byte-order and length, ending up at the start
    // of the log record itself. Use the byte order to properly
    // set the CDR stream for extracting the contents.
    cdr >> ACE_InputCDR::to_boolean (byte_order);
    cdr.reset_byte_order (byte_order);
    cdr >> length;
    ACE_Log_Record log_record;
    cdr >> log_record;  // Finally extract the <ACE_log_record>.
    log_record.print (mblk->rd_ptr (), 1, cerr);
  }
  return mblk->total_length ();
}


int Logging_Handler::log_record ()
{
  ACE_Message_Block *mblk = 0;
  if (recv_log_record (mblk) == -1)
    return -1;
  else {
    int result = write_log_record (mblk);
    mblk->release (); // Free up the contents.
    return result == -1 ? -1 : 0;
  }
}
发表于 2008-11-18 17:43:26 | 显示全部楼层
要看书。
神说:学好ACE,要看书。。。
发表于 2008-11-18 17:50:11 | 显示全部楼层
多谢老兄,哎,书籍太难买到了,抢手货,跑了整个西安,只买个一卷,比较郁闷的事情,我研究下老兄发代码
发表于 2008-11-18 17:53:21 | 显示全部楼层
嗷,下面那段是日志服务器的,老兄说的拼数据3个字比较经典,提醒了我,我仔细研究下,客户端我懒得用ACE写,只要服务端能移植到LINUX就OK,深埋显示器中。。。 。。。

一次读一个STRUCT内容,读5次,然后拼在一块,在然后进行后面的处理:lol :lol 这个东西看来就是挺麻烦的,呵呵


我曾经想用集中写入和读的方法,这样简单点,但是实现起来确实挺不容易,初次接触ACE,比较笨拙

[ 本帖最后由 marry 于 2008-11-18 17:57 编辑 ]
发表于 2008-11-18 21:37:46 | 显示全部楼层
ACE的书,在网上买。以前已经重印了一次,应该还能买的到。实在不行,淘宝上找找。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 08:12 , Processed in 0.019108 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表