论坛首页 入门技术论坛

Graceful Java Programming 优雅Java编程 之Socket Client

浏览 24466 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-02-13  
linliangyi2007 写道
danielzhan 写道
我做过的一个项目正好相反,是Java的服务端和C++的客户端通讯.
对于Java的Server,大家有什么建议.


在网络通信方面,最终的处理跟语言的干系不大,还是看双方的通信协议是怎样的,一切以通讯协议的特点出发吧。


虽然是这样,但是不同语言还是有各自的最佳实践方式和管用技巧,这个又是不尽相同,不了解语言特性就会走弯路
0 请登录后投票
   发表时间:2009-02-13  
unsid 写道
linliangyi2007 写道
danielzhan 写道
我做过的一个项目正好相反,是Java的服务端和C++的客户端通讯.
对于Java的Server,大家有什么建议.


在网络通信方面,最终的处理跟语言的干系不大,还是看双方的通信协议是怎样的,一切以通讯协议的特点出发吧。


虽然是这样,但是不同语言还是有各自的最佳实践方式和管用技巧,这个又是不尽相同,不了解语言特性就会走弯路


恩,一个新思维,受教了。
大家都来谈谈啊!尤其是做C和C++的高手们,不要吝啬你们的知识啊
0 请登录后投票
   发表时间:2009-02-16  
也就是一socket版的hello world,哪里优雅了?
0 请登录后投票
   发表时间:2009-02-16  
luanma 写道
也就是一socket版的hello world,哪里优雅了?


请问,socket的非hello world版,在java上要怎么写呢!?
0 请登录后投票
   发表时间:2009-02-16  
luanma 写道
也就是一socket版的hello world,哪里优雅了?


何必说这样的话呢,人家愿意分享心得本来就是好事,你如果有什么见解或经验,完全可以写出来呀,撂下这么一句话让人看着实在不舒服,分享有错吗?
0 请登录后投票
   发表时间:2009-02-17  
其实楼上有位仁兄回复得不错,楼主说他急了些,没看后面你的回复,但我倒觉得他是指出了你回复里的一些问题。

使用char传输,字节长度是不同的,但java的charset支持针对各种常见编码字符集转换来获得正确的String(当然,如果你并不是文本,那甚至不需要考虑这个),java中之所以倾向使用byte,是因为要支持多种字符集编码方式,增加了coder可能出错地处理了字符的可能性,而byte作为原始方式就能便于修改,并同不同的字符集编码方式快速转换对接。

http中有Content-length,但是你的传输只是基于tcp,并不一定是http,所以长度设置并不一定可用是吧。这是很没法子的,我不肯定基于\0的识别方式能够有效判断传输结束,除非加上一个关键条件,那就是C++服务器上发送的每个数值都是2bytes的,这样是你用char接收的原因吧,但不指定inputstream的charset方式,read到的char却不一定就是服务器发送过来的两两字节对应,因为charset编码会按特定方式解码byte字节数组,补码返回char,这个过程中\0可能作为实际字符的一部分而被忽略。
0 请登录后投票
   发表时间:2009-02-17   最后修改:2009-02-17
我的理解:

socket传输本身是byte字节流,socket底层发送单位是segment,对端判断是否发送完毕的方法是:

1.对端关闭连接,这种情况很好判断,我只记得非阻塞IO
Java中 read返回 -1    ,  如果本次没有读到数据返回 0
C中    read返回  0    ,  如果本次没有读到数据得到一个EWOULDBLOCK 或EAGAIN错误,read返回 -1

2.通过协议判断,二进制协议可以参照CMPP,SGIP看看,文本协议可以参照Memcached的
该读几个字节结束在协议中都是规定好的

至于字符占多少字节什么的,跟Socket没有任何关系,传输层的东西和表示层的东西怎么能一起考虑呢
0 请登录后投票
   发表时间:2009-02-17  
djsl6071 写道
其实楼上有位仁兄回复得不错,楼主说他急了些,没看后面你的回复,但我倒觉得他是指出了你回复里的一些问题。

使用char传输,字节长度是不同的,但java的charset支持针对各种常见编码字符集转换来获得正确的String(当然,如果你并不是文本,那甚至不需要考虑这个),java中之所以倾向使用byte,是因为要支持多种字符集编码方式,增加了coder可能出错地处理了字符的可能性,而byte作为原始方式就能便于修改,并同不同的字符集编码方式快速转换对接。

http中有Content-length,但是你的传输只是基于tcp,并不一定是http,所以长度设置并不一定可用是吧。这是很没法子的,我不肯定基于\0的识别方式能够有效判断传输结束,除非加上一个关键条件,那就是C++服务器上发送的每个数值都是2bytes的,这样是你用char接收的原因吧,但不指定inputstream的charset方式,read到的char却不一定就是服务器发送过来的两两字节对应,因为charset编码会按特定方式解码byte字节数组,补码返回char,这个过程中\0可能作为实际字符的一部分而被忽略。


我同意你说的对java charset的顾虑,但我之所以会直接使用java的read方法,本身就有应用的默认条件的。我们的通讯中只会传输英文和数字,不出现非标准ascii的字符。在这样的前提下为什么不直接使用java默认的api呢,否则就是对java api的浪费了。

还有你对content-length的理解太片面了,你一下子就说到了http,实际上很多基于TCP的通讯协议有自己的报文格式,里面都有固定的长度描述字段的。如果你做过一些短信网关类似的通讯,就经常有这样的协议。

第三,有你说的\0字符因为charset编码被忽略也是不正确的,在实验中,我们打印出了这个标准的ascii字符,它可是ascii编码的第一个字符啊。可以确定的是,它没有因为编码而被忽略。
0 请登录后投票
   发表时间:2009-02-17  
bachmozart 写道
我的理解:

socket传输本身是byte字节流,socket底层发送单位是segment,对端判断是否发送完毕的方法是:

1.对端关闭连接,这种情况很好判断,我只记得非阻塞IO
Java中 read返回 -1    ,  如果本次没有读到数据返回 0
C中    read返回  0    ,  如果本次没有读到数据得到一个EWOULDBLOCK 或EAGAIN错误,read返回 -1

2.通过协议判断,二进制协议可以参照CMPP,SGIP看看,文本协议可以参照Memcached的
该读几个字节结束在协议中都是规定好的

至于字符占多少字节什么的,跟Socket没有任何关系,传输层的东西和表示层的东西怎么能一起考虑呢


正解!!我正怀疑java中read出的-1是不是因为对方关闭了输出端链路造成的,你的说法印证了我的猜测(偷懒了,没有自己做试验,哈哈)

第二点中说的协议,也正是我上述说的content length的判断方式,跟字符编码无关!
跟楼上的英雄所见啊,哈哈!


这里再次重申,我的demo程序中只需要读取标准ascii码,才写成了read char的方式,这是在正确的场合恰当使用java
api的做法!!!



0 请登录后投票
   发表时间:2009-02-17  
luanma 写道
也就是一socket版的hello world,哪里优雅了?


非 hello world 的代码贴上十几屏,你愿意读吗?
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics