急:基于tcp协议,关于socket读写数据大小问题

deadphenix 2004-12-27 06:53:09
我用java做一程序与unix的c通信,基于tcp协议流模式。
我这端是服务器端,使用ServerSocket建立监听。unix上对方程序可以与我的服务器建立连接,并读写数据。
但问题随之而来:我接受unix客户请求数据后,根据数据要求返回一个数据结果。unix客户端接收到数据但大小不符合。我返回了174长度的数组,而unix上对方程序只接收到114长度的数据包。请只知道的兄弟解惑。
...全文
301 点赞 收藏 15
写回复
15 条回复
IT老兵 2004年12月28日
一个一个字节取,试试看。
同时请校验2端的编码方式是否一样,但是看起来这个应该没有什么问题,因为你只是用到byte[]。
看看c代码是如何获取数据的,因为c中的0会被认为字符串结束符的。所以最好只要以byte操作比较好。
回复 点赞
deadphenix 2004年12月28日
没有成功,仍然数据没收全。另外,若返回数据长度比较小的话则成功。
回复 点赞
deadphenix 2004年12月28日
感谢 ChDw(米) , zedk928(其实我是一个卧底!) 的回复
sock.getSendBufferSize()出来是8k应该没问题,我现在在看是不是:
BufferedOutputStream out = new BufferedOutputStream(outputToSocket);的原因
BufferedOutputStream默认的size是512,我打算换成:
BufferedOutputStream out = new BufferedOutputStream(outputToSocket,8192);
回复 点赞
zhangyu6050 2004年12月28日
o
回复 点赞
ChDw 2004年12月28日
这个我觉得应该是C客户端有问题吧,怎么能够认为一个包就是结束呢?你可以试试
sock.setSendBufferSize来看看,但是应该说是C方面存在问题的。
回复 点赞
deadphenix 2004年12月28日
是的。
问题可能找到了,但我不知道如何解决,c客户端没有使用流机制,在接收到一个数据包后就认为当前socket通信结束。
我如何才能使我的socket在out.write(answer)时只产生一个数据包啊?
回复 点赞
zedk928 2004年12月28日
你调试的时候buildCode()返回的是[010122345 5436542 3232]吗?
如果是的,那可能是通讯中的字符串丢失了
回复 点赞
deadphenix 2004年12月28日
解决了,网络监视了一下,发现我发出的数据包含'\0',对方是C语言接收,此时它就判断socket结束了。实际上,从第115个byte开始“空格”都不是真的空格ascii'32',而是ascii'00'。
这里要再次感谢takecare(大厅)、ChDw(米)、zedk928(其实我是一个卧底!) ,:)
回复 点赞
xiaokaiye 2004年12月28日
最好的做法是在每个包结尾加一个结束符,这样能保证包的完整性!
当然如果能控制好长度,应该没有问题。
或者:建议在包的开头几位(约定)存放当前包的长度,然后根据长度来读取报文。

其实就是怎么保证包体的完整性的问题。
回复 点赞
IT老兵 2004年12月28日
同时建议打印出来
byte[] answer = buildCode();//得到返回数据[010122345 5436542 3232]
是不是确实如你所说的数据,你那些[xxx xxx xxx]里的x到底是什么进制的值?
其实这个就是你们c-java之间的应用曾协议的问题。如果你传了一个byte[],但是c端以字符串的方式接受当然就不对了,一定要做到encoder/decoder是可逆的。

btw,你的32如果是10进制标示的ASCII的话,那可就是“空格”哦。
回复 点赞
deadphenix 2004年12月27日
是不是java与c在使用socket通信时有问题呢?但按照TCP协议规范,应该不存在这种问题啊。
回复 点赞
deadphenix 2004年12月27日
看了网上好些地方,好像有不少人遇到这样的问题,但都没有给出解决的办法。
回复 点赞
deadphenix 2004年12月27日
不好意思哈,UNIX下C语言客户端我不知道,只知道他与我之间定义的协议,他提交一个请求如:[010022345],我根据请求返回一个值如:[010122345 5436542 3232](变长)byte数组,结果他接受到[010122345 5436542 ],而3232就没收到了,服务器处理代码如下:

try {
byte[] readBytes,writeBytes;
OutputStream outputToSocket = connection.getOutputStream();
InputStream inputFromSocket = connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(inputFromSocket);
BufferedOutputStream out = new BufferedOutputStream(outputToSocket);
Request request = null;
Response response = null;
readBytes = new byte[9];
in.read(readBytes);//读取请求[010022345]
byte[] answer = buildCode();//得到返回数据[010122345 5436542 3232]
out.write(answer);//写入返回数据
out.flush();
out.close();
in.close();
} catch (Exception e) {
socketListener.getLog().write("error***处理当前连接时出现例外:"+e);
}
finally{
try{
connection.close();
connection = null;
} catch (Exception e){
System.out.println(e)
}
}
回复 点赞
tomcatjava 2004年12月27日
你是怎么设计服务器端和客户端的?
回复 点赞
yzjloveme 2004年12月27日
关注中!
回复 点赞
发动态
发帖子
Java EE
创建于2007-09-28

3.7w+

社区成员

22.5w+

社区内容

J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区公告
暂无公告