【转】在Java与C程序间进行socket通信的讨论

1. 背景 
使用socket在Java程序与C程序间进行进程间通信。本文主要描述了在同C程序进行通信的Client端的Java实现功能。

1.1. 使用的语言 
Client端:Java,JVM(JDK1.3) 
Server端:C,UNIX(Sun Solaris)

1.2. 讨论范围 
数据发送:只涉及到Java中int整型系列的讨论,包括byte,short,int。 
数据接受:涉及到byte,short,int,long,float,double,char。

1.3.Java与C的数据类型的比较 
Type Java C 
short 2-Byte 2-Byte 
int 4-Byte 4-Byte 
long 8-Byte 4-Byte 
float 4-Byte 4-Byte 
double 8-Byte 8-Byte 
boolean 1-bit N/A 
byte 1-Byte N/A 
char 2-Byte 1-Byte

2. 实现 
输出流:使用OutputStream流发送数据到C程序端。 
输入流:使用DataInputStream流从C程序端接受数据

2.1. 数据发送 
由于DataOutputStream流对于Java各个基本数据类型都相应地提供了“写”方法,如wrightShort和wrightInt等,因此当进行进程间通信(sockect通信)时,我们总是优先考虑使用DataOutputStream流。 
下面我们对DataOutputStream流及其成员方法进行分析:

2.1.1. DataOutputStream流 
DataOutputStream流实现了接口DataOutput。 
本文只讨论writeByte(int v)、writeShort(int v)和writeInt(int v)部分(这是因为我们需要发送的数据只涉及到int,short和byte,其它的long,double等则不在这里介绍),而且它们都有一个共同的特征,即唯一的int类型的输入参数。 
这些成员方法的功能描述也为我们以后手动进行字节顺序转换,提供了理论依据。 
2.1.2. 网络字节顺序 
规定:网络上传输的数据统一采用Big Endian格式(即“高字节在前”),我们称之为“网络字节顺序”(network byte order)。

Big Endian格式: 
高字节 低字节 
1 2 3 4 
Byte[0] byte[1] byte[2] byte[3]输出缓冲区

因此,无论本机字节顺序采用的那种顺序,在发送到网络之前都要转化为网络字节顺序,才能进行传输。特别是在Java与C两种不同语言的应用程序间进行通信时,这一点优为重要。(若是两个Java程序间通信时可能只要保证接受与发送采用相同的字节顺序,则可以不进行转换格式,但这种做法并不好,不具有良好的移植性)

2.1.3. 数据发送:手动字节转换 / writeInt方法 
以writeInt(int v)为例进行描述: 
阅读DataOutput的writeInt(int v)方法的文档可知: 
使用writeInt方法可以写一个4-byte的int值v到输出流,其字节顺序为:

(byte)(0xff & (v >> 24)) byte[0] 高字节 
(byte)(0xff & (v >> 16)) byte[1] 
(byte)(0xff & (v >> 8)) byte[2] 
(byte)(0xff & v) byte[3] 低字节 
这样的字节顺序为Big Endian格式,标准的“网络字节顺序”。 
但是在实际工作中输出流采用DataOutputStream.readInt(int)方法时写数据出错,需要自己手动按照以上所说的对需要写的v值进行转换(通过移位完成),转换的代码如下所示,可参见程序SocketClient.java中的ByteConverter.intToByte()方法。 
static public final byte[] intToByte( 
int value, int offset, int length, byte[] buffer) 
{ // High byte first on network 
for (int i=0,j=length-1; i<length; i++,j--) { 
if ( j+offset >= 0 && j+offset < 1024 ) { 
buffer[j+offset] = (byte)( (value >> i*8) & 0xFF ); 
} else { 
System.out.println ( 
"Array index out of the bounds:Index=" + (j+offset) ); 


return buffer; 
}

2.2. 数据接收 
同数据发送相同,由于DataInputStream流对于Java各个基本数据类型都相应地提供了“读”方法,如readShort和readInt等,因此当进行进程间通信(sockect通信)时,我们总是优先考虑使用DataInputStream流。 
而与数据发送不同的是,DataInputStream下的成员方法经实际测试,“基本上可以”根据数据类型正确读出相应的数值。 
但并非完美,特别是与不同语言的应用程序进行通信时(如C)。

根据表1(Java与C的数据类型的比较)可知: 
(1)long型的字节数在Java和C中相差4个字节: 
因此由readLong方法读来的数值应进行带符号的右移32(4-byte)位才能得到在C程序中相应的long型数值。 
Type Java C 
long 8-Byte 4-Byte

(2)由于Java中的char型为2个字节,C中的char型为1个字节,因此不能使用readChar方法来读取C程序中的char数值。 
然而在Java中byte型为1个字节长,因此可以使用readByte方法得到C程序中的char型数值。 
Type Java C 
byte 1-Byte N/A 
char 2-Byte 1-Byte

时间: 2024-10-08 10:44:26

【转】在Java与C程序间进行socket通信的讨论的相关文章

iOS程序间使用scheme通信

在 iOS 里,由于沙盒机制,程序之间都是相互隔离,所以想要从一个程序跳转到另一个程序一般情况是做不到,幸好 iOS 程序可以很方便的注册自己的 URL Scheme,这样就可以通过打开特定 URL 的方式来传递参数给另外一个程序,并启动它. 1.首先在A程序中注册scheme, 注意结构体不要搞乱,我开始就是因为结构体顺序不对,导致一直跳转 不成功. 这样的话就设置成功了scheme了.接下来就是去B程序调用该程序了. 2.新建一个B程序,调用A 新建一个button,添加点击事件 当点击该按

Java NIO实现非阻塞式socket通信

博主知识水平有限,只能提供一个个人的狭隘的理解,如果有新人读到这儿,建议看一下其他教程或者API,如果不明白,再来看一下:如果有dalao读到这儿,希望能指出理解中的问题~谢谢 Java提供了用于网络通信的socket和serversocket包,然而实现方式是阻塞式的,同一时间点上只能进行一个连接,这会带来不好的体验.当然了,我们也可以通过不断创建线程的方式管理连接,但线程多了的话反而会降低效率.于是Java推出了非阻塞式IO--channel.并且channel提供关于网络通信的相关chan

java学习小笔记(三.socket通信)【转】

三,socket通信1.http://blog.csdn.net/kongxx/article/details/7288896这个人写的关于socket通信不错,循序渐进式的讲解,用代码示例说明,运用流和socket进行远程通讯 2.最简单的socket是一个服务端对应一个客户端 server的写法 ServerSocket server = new ServerSocket(10000); Socket socket = server.accept(); BufferedReader in =

170407、java基于nio工作方式的socket通信

客户端代码: /** * */ package com.bobohe.nio; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio

Java网络编程之tcp的socket通信

1.客户端MyClient.java 1 import java.io.*; 2 import java.net.*; 3 4 public class MyClient 5 { 6 public static void main(String[] args)throws Exception 7 { 8 Socket s = new Socket("192.168.1.1" , 30000); 9 // 客户端启动ClientThread线程不断读取来自服务器的数据 10 new Th

MVC模式在Java web 应用程序的实现

一.MVC简介 MVC(Model-View-Controller)模型-视图-控制器,最早由Trygve Reenskaug在1978年提出,是施乐帕罗奥多研究中心(Xerox PARC)在20世纪80年代为程序语言Smalltalk发明的一种软件架构.MVC模式的目的是实现一种动态的程序设计,使后续对程序的修改和扩展简化,并且使程序某一部分的重复利用成为可能.除此之外,此模式通过对复杂度的简化,使程序结构更加直观.软件系统通过对自身基本部分分离的同时也赋予了各个基本部分应有的功能. Mode

Java命令行程序构建工具-airline

以前对于开发Java命令行程序,我都是很头大的,命令行程序麻烦的是解析参数,以及一些帮助信息,今天在研究接口测试时偶然发现了一个工具可以让你快速构建命令行程序 github地址 airline 导入jar包 airline jar 在maven仓库里搜索适合你构建系统的语句 代码 我找了个解析har文件的项目,来讲解开发过程 定制自己的命令行 我的命令行以doctorq作为命令,参数为company,命令的完整格式应该为doctorq company XXXXX. @Command(name="

福利贴——爬取美女图片的Java爬虫小程序代码

自己做的一个Java爬虫小程序 废话不多说,先上图. 文件夹命名是用标签缩写,如果大家看得不顺眼可以等下载完成后手动改一下,比如像有强迫症的我一样... 这是挂了一个晚上下载的总大小,不过还有很多因为一些问题没有遍历下载到,而且会产生很多空文件,最下面我附带了一个递归删除空文件夹的小程序代码. 接下来是文件夹内部~ 图片存放位置默认为d:\picture,可在程序中更改,main函数的开头就是,有注释.爬取的网站为http://www.mmonly.cc/,大家有更好的资源网站可以私我. 爬虫源

iOS应用程序间共享数据(转)

我们知道iOS由于沙盒的存在,应用程序不能越过自己的区域去访问别的存储空间的内容,不过可能有许多场景我们需要在应用程序之间共享数据,比如多个应用共用用户名密码进行登录等.虽然我们不能直接通过文件系统来分享数据,不过还是有些方法可以实现,为了方便说明,这里同时创建了两个工程Example1和Example2,实现这两个app之间的信息共享,Example1负责写数据,Example2负责读数据,具体的demo代码可以到这里获取 UIPasteboard 剪贴板是应用程序之间传递数据的简单方式,建议