Uploaded by 安旭

用Java实现基于TCPIP协议的网络通信程序

advertisement
J o u rna l o f W uha n In s titu te o f Educa tio na l S c ie nce
VOL. 4 , NO. 4. 2006
用 Java实现基于 TCP / IP协议的网络通信程序
刘 嵩
[摘要 ] 随着互联网的飞速发展 ,程序开发已经由早期开发单机程序过渡到网络互联
的程序开发 。 Java 语言提供了一套功能强大的 AP I(应用编程接口 )来实现网络编程所需
的网络通信功能 。这套 AP I使 Java 程序员不用考虑复杂的网络协议以及底层的数据传
输方式 ,而直接用面向对象的思想来实现网络传输 。
[关键词 ] JAVA; 网络 ; SOCKET; CL IENT / SERVER
[作者简介 ]刘嵩 : 武汉软件职业学院教师 。 (武汉
430205 )
随着互联网的普及 ,程序开发过程中不可避
程之间进行 , 通信完毕关闭此联接过程 。使用无
免的要求实现网络互连通信功能 。网络上的系统
联接方式时其系统开销比无联接方式小 , 但通信
结构多为客户端 /服务器模式 ,服务器端负责数据
链路提供了不可靠的数据报服务 , 不能保证信源
和图像等的存储 、
维护 、
管理以及传递 ,客户端则负
所传输的数据一定能够到达信宿 。在该方式下 ,
责人机界面的操作 、
送出需求及显示收回的数据 。
通信双方不必创建一个联接过程和建立一条通讯
下面介绍一下如何使用 Java来进行网络编程 :
链路 ,网络通信操作在不同的主机和进程之间转
发进行 。 TCP / IP系统中的端口号是一个 16 位的
一、
基本原理
数字 ,它的范围是 0 ~65535。实际上 , 小于 1024
socket是指在一个特定编程模型下进程间通
的端口号保留给预定义的服务 , 而且除非要和那
信链路的端点 。一个 socket包括两个流 : 一个输
些服务之一进行通信 (例如 telnet, SM TP 邮件和
入流和一个输出流 。如果一个进程要通过网络向
ftp 等 ) ,否则你不应该使用它们 。客户和服务器
另一个进程发送数据 , 只需简单地写入与 socket
必须事先约定所使用的端口 。如果系统两部分所
相关联的输出流 。一个进程通过从与 socket相关
使用的端口不一致 ,那就不能进行通信 。
联的输入流读来读取另一个进程所写的数据 。如
果要建立连接 , 一台机器必须运行一个进程来等
二、
实现方法
待连接 ,而另一台机器必须试图到达第一台机器 。
Java 中输入 /输出流概念 : 过滤流 Data Input2
这和电话系统类似 ; 一方必须发起呼叫 ,而另一方
Stream 和 DataOutputStream 除了分别作为 FilterIn2
在此时必须等待电话呼叫 。 socket通信机制提供
putStream 和 FilterOutputStream 的子类外 , 还分别
了两种通讯方式 : 有联接和无联接方式 ,分别面向
实现 了 接 口 Data Input 和 DataOutput。接 口 Da2
不同的应用需求 。使用有联接方式时 , 通信链路
ta Input 中定义的方法主要包括从流中读取基本
提供了可靠的 , 全双工的字节流服务 。在该方式
类型的数据 、
读取一行数据 、
或者读取指定长度的
下 ,通信双方必须创建一个联接过程并建立一条
字节数 ,如 readBoolean ( ) read Int ( ) 、readL ine ( ) 、
通讯链路 ,以后的网络通信操作完全在这一对进
readFully ( )等 。接口 DataOutput中定义的方法主
武汉市教育科学研究院学报 67
VOL. 4 , NO. 4. 2006
J o u rna l o f W uha n In s titu te o f Educa tio na l S c ie nce
要是向流中写入基本类型的数据或者写入一定长
OutputStream os = s. getO utputStream ( )
度的字节数组 ,如 w riteChar ( ) 、w riteDouble ( ) Da2
/ /省略从输入流读取数据代码
ta InputStream 可以从所连接的输入流中读取与机
os. close ( ) ;
器无关的基本类型数据 , 用以实现一种独立于具
is. close ( ) ;
体平台的输入方式 ; Data InputStream 可以向所连
s. close ( ) ;
接的输出流写入基本类型的数据 。
(二 )服务器端的编程流程
多线程使应用程序可以同时进行不同的操作
打开 ServerSocket创建一个服务器型套接字
处理不同的事件 。在多线程机制中 , 不同的线程
和一个普通套接字 , 服务器型套接字在指定端为
处理不同的任务 ,他们之间互不干涉 ,不会由于一
客户端请求的 Socket服务 ; 使用 ServerSocket类的
处等待影响其他部分 , 这样容易实现网络上的实
accep t ( )方法使服务器型套接字处于监听状态并
时交互操作 。 Java 程序可以有多个执行线程 , 如
把监听结果返回给普通套接字 ; 为该普通套接字
可以让一个线程进行复杂的计算 , 而让另一个线
创建输入和输出流 ; 从输入和输出流中读入或写
程与用户进行交互 , 这样用户可以在不中断计算
入字节流 ,进行相应的处理 ,并将结果返回给客户
线程的前提下与系统进行交互 。多线程保证了较
端 ; 在客户端和服务器工作结束后关闭所有的对
高的执行效率 。
象 ,如服务器型的套接字 , 普通套接字 , 输入和输
出流 。正是由于 Java 系统具有基于 Socket 的灵
三、
具体实现
活通信机制 ,因而其应用程序能自由地打开和访
App lication 同 App let的通信 ,两端通过 Sock2
问网络上的对象 ,就象在本地文件系统中一样 。
et机制进行连接 ,通信过程如图 1 所示 :
下面的代码在 4331 端口创建了一个 Server2
Socket对象负责处理客户端的套接字请求 , 为每
一个用户请求套接字启动一个新的线程 , 并且通
过处理请求得到的套接字对象获取输入输出流进
行数据传输 。
try{
server = new ServerSocket ( 4331 ) ; }
catch ( IO Excep tion e1 )
{ System. out. p rintln (“正 在 监 听 ”) ; / / Ser2
verSocket对象不能重复创建
(一 )客户端的编程流程
打开 Socket,新建一个套接字 ,为套接字建立
try{
you = server. accep t ( ) ; / /等待用户连接 }
一个输入和输出流 ; 根据服务器协议从套接字读
catch ( IO Excep tion e ) { }
出或向套接字写入 ,清除套接字和输入 /输出流 。
if ( you! = null) {
下面的代码创建了一个服务程序主机地址为
198. 163. 227. 6,端口号为 4331 的 Socket对象 ,
new Server_thread ( you ) . start ( ) ; / /为每个客
户启动一个专门的线程 }
然后从这个新创建的 Socket对象中获取输入输出
... ...
流进行数据传输 ,然后再关闭流和 Socket对象 。
class Server_thread extends Thread{
Socket s = new Socket (“198. 163. 227. 6 ”,
4331 ) ;
InputStream is = s. getInputStream ( ) ;
68 武汉市教育科学研究院学报
Socket socket; Connection Con = null; Statement
Stm t = null;
DataOutputStream out = null; (下转第 71 页 )
J o u rna l o f W uha n In s titu te o f Educa tio na l S c ie nce
VOL. 4 , NO. 4. 2006
这样得到了 vp tr这个指针 , 然后用一个 unsigned
( 3 f) ( ) ;
char指针运算偏移量 , 得到的结果再次输入 getp
delete p; }
( ) ,这次得到的就应该是正确的函数体的位置
运行结果为 :
了。
A: : fun1 ( )
那么它到底能不能正确工作呢 ? 我们修改
main ( ) 来测试一下 :
int main ( )
A: : fun2 ( )
B ase: : fun3 ( )
通过上述方法 , 我们获取了对象的 VPTR , 在
{B ase 3 p = new A;
它的体外执行了它的虚函数 , 也对 VPTR 在多态
fun f = getfun ( p , 0 ) ;
中的应用有了深刻的认识 . 相信读者以后遇到运
( 3 f) ( ) ;
行时的多态感觉会好多了吧 。
f = getfun ( p , 1 ) ;
( 3 f) ( ) ;
〔责任编辑 : 陈光兰 〕
f = getfun ( p , 2 ) ;
(上接第 68 页 ) Data InputStream in = null; i
Server_thread ( Socket t)
有主机 IP地址或主机名参数 。
(二 )连接建立好之后应确定输入和输出流 。
{ socket = t;
起 初 程 序 中 用 的 是 Data InputStream 和 Print2
try { / /通过套接字获取输入输出流
Stream , 结果只能传输英文 , 传输中文时产生乱
in = new Data InputStream ( socket. getInput2
码 ,将 PrintStream 改为 DataOutputStream , 使用 re2
Stream ( ) ) ;
out = new DataOutputStream ( socket. getO utput2
Stream ( ) ) ; }
catch ( IO Excep tion e ) { } }
Java 语 言 为 我 们 提 供 了 强 大 的 网 络 开 发
adUTF ( ) 和 w riteUTF ( ) 方法后 , 中文传输问题得
到解决 。
(三 )如果一个使用某端口的程序没有关闭 ,
另一个程序就不能使用这个端口 。
参考文献 :
AP I,使我们能够通过简单的面向对象的编程思想
[ 1 ]B ruce Eckel. Java编程思想 [M ]. 机械工业出版社
来通过 TCP / IP 协议进行复杂的网络通信 。但是
[ 2 ] Cay S. Horstm ann, Gary Cornell. Java 2 核心技术 (第 6 版 )
在实际运用中还需要注意以下问题 :
(一 )在建立 Socket连接时 , 两端的端口号必
须设为一致 , 否则建立不了连接 。服务器端必须
卷 I: 基础知识 [M ]. 机械工业出版社
〔责任编辑 : 陈光兰 〕
武汉市教育科学研究院学报 71
Download