Chinaunix

标题: socket编程:转发报文如何处理 [打印本页]

作者: BIOO    时间: 2009-09-23 09:06
标题: socket编程:转发报文如何处理
简单流程:
无法打开文件“D:\dev\ACE_wrappers/include.obj
接受来自E 的报文
1、侦听某端口E
2、接受业务报文
3、对业务报文解压缩lz77
4、md5校验文件一致性,如果不一致则再次请求该报文?一致转5
5、转发经过md5校验一致的报文到端口b(转至T)
接收来自t报文
1、侦听某端口T
2、接受业务报文
3、md5校验文件生成md5值填入报文
4、lz77压缩
5、转发经过MD5、lz77处理的报文到端口C(发至E方)

现在不考虑中间的压缩和md5,只考虑转发,应该怎么处理?谢谢。业务报文都小于1k
作者: yulihua49    时间: 2009-09-23 09:21
原帖由 BIOO 于 2009-9-23 09:06 发表
简单流程:
无法打开文件“D:\dev\ACE_wrappers/include.obj
接受来自E 的报文
1、侦听某端口E
2、接受业务报文
3、对业务报文解压缩lz77
4、md5校验文件一致性,如果不一致则再次请求该报文?一致转5
5 ...

就按你说的处理。
作者: BIOO    时间: 2009-09-23 09:34
业务逻辑能想到,具体程序要怎么写呢?不知所错了
作者: BIOO    时间: 2009-09-23 09:45
要写成两个程序?
到底哪个算是server,哪个算是client呢
作者: gawk    时间: 2009-09-23 09:50
当服务器又当客户端
作者: BIOO    时间: 2009-09-23 10:02
有没有demo呢?想找个demo看看
作者: BIOO    时间: 2009-09-23 10:15
这样需要考虑不同的报文长度吗?
作者: @sky    时间: 2009-09-23 10:27
意思不就是端口映射么
作者: BIOO    时间: 2009-09-23 10:40
端口映射可以完成?怎么具体做呢?
作者: huxk    时间: 2009-09-23 12:53
看netcat,core.c core_readwrite函数,或者看tinyproxy handle_connection函数,或者看tcpproxy proxy_request函数,

或者看unix network programming 里面有一个从标准输入读数据发到服务器,然后服务器回应相应数据给标准输出的程序,

具体代码见strclinonb.c中的str_cli函数。基本思路都是select模式。找一个改造改造。根据自己需要用blocking或者non-blocking模式。

[ 本帖最后由 huxk 于 2009-9-23 13:02 编辑 ]
作者: BIOO    时间: 2009-09-23 14:32
谢谢huxk,ace如何实现呢?windows下面
作者: huxk    时间: 2009-09-23 14:57
如果用ace的话关注重心转移了,你要研究ace的框架以及模式,然后如果搞明白了,实现这个任务应该不是难事。

但是ace不是一下子就能搞明白的。尽管如此,你还是可以上ace网站看看,里面有很多文档。它涉及好多设计模式

面向对象,但偶不喜欢面向对象。
作者: BIOO    时间: 2009-09-23 16:35
比较抽象,看看先。
select模式
作者: BIOO    时间: 2009-09-23 16:52
感觉很像ace的echo server问题。
我苦于自己总是没有什么OO的思想。
作者: BIOO    时间: 2009-09-23 16:53
现有real code搞起来再说了,主要是先把框架搞起来。real code
作者: huxk    时间: 2009-09-23 17:27
把客户端和服务端的套接字加入select读集合

判断,当客户端可读时,读取数据,用阻塞模式,然后write到服务器

当服务端可读时,读取数据,用阻塞模式,write到客户端 就这样,netcat还考虑了网路延迟

另外要注意你和服务端是长连接还是短连接的情况,以便确定打开到服务器连接的时机

框架还用搞吗,照着抄就好了啊

[ 本帖最后由 huxk 于 2009-9-23 17:28 编辑 ]
作者: BIOO    时间: 2009-09-23 17:32
谢谢huxk,需要考虑各中不通报文的长度吗?其实只是做一个repeator的话,我觉得都不要考虑业务报文的长度,直接取最大的报文长度,可否?
作者: huxk    时间: 2009-09-23 18:55
标题: 回复 #17 BIOO 的帖子
一般来说,用read返回的值就可以了。
简单起见,直接用一个大缓冲区去读就ok了,然后转手就write出去,不用考虑长度,
write传入read读取成功时的长度值即可。

至于复杂情况和应用,另当别论。
作者: BIOO    时间: 2009-09-24 10:29
我用ace的echo server大体实现了这个功能,就是我是用string来接收数据的,是不是有问题呢?
而且string不能像char那样定义长度,但是有很多的函数可以直接用,不晓得怎么解决这个问题。
作者: koolcoy    时间: 2009-09-24 10:46
又md5又lz77的~~~。如果程序负载大一点客户绝对嚼了你,骨头都不会吐
作者: BIOO    时间: 2009-09-24 11:26
原帖由 koolcoy 于 2009-9-24 10:46 发表
又md5又lz77的~~~。如果程序负载大一点客户绝对嚼了你,骨头都不会吐


这个是客户的强烈要求。不是某能决定的,某认为不足1k的业务报文,还是专线连接,搞这些都是扯淡。
某只是个小把戏,让他们折腾吧。
只考虑怎么实现这个玩意儿
作者: huxk    时间: 2009-09-24 12:34
用string类?

const int BUFSIZE = 8192;

unsigned   char   *buffer =   new   unsigned   char(BUFSIZE);

这样可以吧
作者: BIOO    时间: 2009-09-24 13:52
简单写了这样一个东西出来。就是如果修改成
const int BUFSIZE = 8192;

unsigned   char   *buffer =   new   unsigned   char(BUFSIZE);

的话是不是我就要把
peer_stream_e .recv( (void*)str.c_str(), str.length() );
改成peer_stream_e .recv( buffer,BUFSIZE);

// acerepeator.cpp : 定义控制台应用程序的入口点。


#include "stdafx.h"



// acesimser.cpp : 定义控制台应用程序的入口点。
//本文件原为echo server 现在将其改装为repeator

#include "stdafx.h"

/*int _tmain(int argc, _TCHAR* argv[])
{
        return 0;
}*/
#include <iostream>
#include <string>
#include "ace/ACE.h"
#include "ace/INET_Addr.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/SOCK_Stream.h"
#include "ace/SOCK_Connector.h"
using namespace std;

int main( int argc, char* argv[] )
{
ACE::init();

//string str("1",1024);
// str.resize( sizeof( "hoooo world9999" ) );
string str;
str.resize( sizeof( "hoooo world999955533322211199988877766555" ) );
//while( 1 ){
//设置服务器地址:用于接收来自e 的业务报文
ACE_INET_Addr peer_addr_e ( 5050, "127.0.0.1" );

ACE_SOCK_Stream peer_stream_e ; //创建被动连接角色对象
ACE_SOCK_Acceptor peer_acceptor_e ; //开启被动连接对象,将对象绑定到一个地址上
peer_acceptor_e .open( peer_addr_e  );  //等待连接
peer_acceptor_e .accept( peer_stream_e  );  //数据通讯
peer_stream_e .recv( (void*)str.c_str(), str.length() );//接收来自客户端的数据
cout << "接收到e 客户端的消息 : " << str << endl;
// peer_stream.send( str.c_str(), str.length() );


/*以下代码将此业务报文str发送到t */

ACE_INET_Addr peer_addr_t ( 5051, "127.0.0.1" );
ACE_SOCK_Stream peer_stream_t ;//定义一个通讯队形

ACE_SOCK_Connector peer_connector_t ;//定义一个主动连接对象
peer_connector_t .connect( peer_stream_t , peer_addr_t  );//发起一个连接

peer_stream_t .send( str.c_str(), str.length() );//发送数据到服务器


cout << "发送到t 的业务报文 : " << str <<endl;



//}
ACE::fini();

system("PAUSE");
return 0;
}

程序写的很幼稚,大家多提建议,谢谢

[ 本帖最后由 BIOO 于 2009-9-24 14:00 编辑 ]
作者: BIOO    时间: 2009-09-24 15:53
大家多提提意见啦,写的太幼稚。
作者: huxk    时间: 2009-09-24 17:30
这种代码我看着总是高深莫测,你实在是很难搞清楚里面到底做了些什么动作。

你这个代码能满足你的需求吗?似乎还是要用reactor或者proactor来做吧。

但是如果对ace这些模式不是非常清楚的话,还是不要用来跑业务,否则,

出了问题麻烦多多。
作者: BIOO    时间: 2009-09-24 21:23
嗯,谢谢huxk,这个倒是能基本满足了。
您说的反应器之类的还没搞清楚呢。
目前只能拿这个代码跑跑玩玩。
read
write等等的还在折腾呢。

ace的东西太多了。不过某的OO意识太差了。
感觉如果只是写个转发程序,是不是就是写一个repeator?假设不进行lz77或者md5之类的话。
作者: BIOO    时间: 2009-09-24 21:34
觉得这种网络通信程序都不知道如何写才能完美
作者: BIOO    时间: 2009-09-29 08:58
觉得关键还是转发程序如何写的好。md5或许可以去掉了




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2