论文部分内容阅读
摘要:随着网络技术与计算机开发语言的发展,越来越多的程序员利用Java来编写网络程序。本文介绍了Socket的通信机制,并使用Java语言、套接字接口(Socket API)技术和多线程相结合的模式实现了多客户端与服务器的并发通信的多人聊天系统。
关键词:Java;Socket;多客户并发;网络通信
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)20-30253-03
Design & Implement of Chat System Based on Socket Multi-user Parallel Communication
MO Zu-qin, OUYANG Yan-jie, MA Kang
(Dept of Computer Eng, Shiyan Technical Institute Eng, Shiyan 442000, China)
Abstract: As internet technic and computer language develop, more and more programmers make use of Java to compile net programme. This paper introduces the mechanism of communications and using the combination of Java language, Socket API technic and the multithreading to implement chat system in which multi-user and server can communicate parallel.
key words: Java; Socket; multi-user send parallel; Net communication
1 引言
Java是一種可以编写跨平台应用软件的面向对象的程序设计语言,网络应用是Java语言取得成功的领域之一,它已经成为现在Internet上最流行的一种编程语言。网络编程的目的就是直接或间接地通过网络协议与其它计算机进行通讯。两台计算机通讯需解决两个主要问题:一是如何准确定位网络上的主机;二是找到主机后如何可靠有效地进行数据传输。
Java语言作为网络编程语言,提供了强大的网络编程接口。针对网络通信的不同层次,Java提供的网络功能有四大类:InetAddress、URL、Socket、Datagram。Socket是Internet使用的协议组TCP/IP的组合,实现了两台主机之间通过端口进行网络通信。Java.net包中提供Socket类,隐藏了Socket的实现细节,不需要开发者编写接口程序,而可以快速的实现网络的通信。[1]
2 Socket的通信
2.1 Socket通信机制
在Java中,可以使用两种Socket方式,即流式Socket和数据报式Socket。流式Socket提供了双向的、有序的、无重复、可靠的的数据流服务,采用的是一种TCP协议。数据报式Socket支持双向的数据流,但不保证是可靠的、有序的、无重复的传输,采用的是UDP协议。[1]两种Socket相比较而言,流式Socket具有较高的安全性,但有一定的额外开销。而数据报式Socket与之相反。笔者根据实际情况采用的是流式Socket方式。
基于TCP协议的流式Socket实现网络通信的类有两个:在客户端的Socket类和在服务器端的ServerSocket类。无论一个Socket通信程序的功能多么齐全,程序多么复杂,Socket基本
结构都是一样的,都包括以下四个基本步骤:
(1)在客户端和服务器端创建Socket和ServerSocket实例;
(2)打开连接到Socket的输入/输出流;
(3)利用输入/输出流,按照一定的协议对Socket进行读/写操作;
(4)关闭输入/输出流和Socket。
Socket通信机制框图见图1。
2.2 Socket的多客户端并发通信
支持多个客户端的Socket通信实现方法有多种:方法一,在一台计算机上一次启动多个服务器程序(端口号必须不同);方法二,将服务器程序写成多线程的,不同处理线程为不同的客户服务,主线程只负责循环等待,处理线程负责网络连接,接收客户输入的信息。
实现多个客户与服务器并发通信,就像服务器与自己连接一样,笔者认为最好引入多线程机制。多线程正好是Java提供的一个重要机制,支持多个程序并发执行。服务器端每当建立一个新的Socket连接,主线程就启动一个新的线程,负责服务器与客户端的通信;而主线程继续等待下一个客户端的连接。当客户端断开连接后,子线程释放其占用的所有Socket资源[3]。多线程支持多客户端的具体框图见图2。
3 多客户端聊天程序的设计
系统主要分为两大部分:TCP服务器Server和客户端Client。
3.1 服务器端程序编写
服务器端等待用户连接,如有用户发送连接请求后,创建一个用户实例,记录客户端的相关信息,维护与该用户的连接。根据聊天的接收人信息,再将接收的数据传输给客户端。当用户断开连接时,关闭用户实例,断开此用户连接。[2]主要步骤如下:
(1) 启动服务器
try {
server=new ServerSocket(port);//初始化服务器套接字
while(true){socket=server.accept(); //等待客户连接
System.err.println(socket.getInetAddress()+"连接\n"); //得到客户机地址
Client client=new Client(socket);//实例化一个客户线程
clients.addElement(client);//增加客户线程到向量中
client.start(); //启动线程
notifyChatRoom(); //监视聊天室连接变化
} }catch(Exception ex) {
ex.printStackTrace(); //输出出错信息}
(2) 更新在线用户
for(int i=0;i {//elementAt方法返回在特定位置的元素,返回的元素为Object对象
Client c=(Client)clients.elementAt(i);
newUser.append(":"+c.name);//客户端姓名字符串,取得客户端的名字
}sendClients(newUser); //把取得的客户端名字发送给每个客户端
(3) 多线程的实现
聊天室的服务器采用多线程实现,每当一个新的用户连接到服务器时,就实例化一个新的线程来与该客户端通信。Client类负责维护客户端的相关信息,比如IP地址、聊天室中的用户名、连接端口等,并实现了信息发送的send方法。主要代码如下。
//得到输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintStream ps=new PrintStream(s.getOutputStream()); //得到输出流
String info=reader.readLine(); //读取接受到的信息
ps.println(msg); //输出信息
ps.flush();
public void run(){while(true){
String line=null;
try{line=reader.readLine();//读取数据流
}catch(IOException ex){
ex.printStackTrace(); //输出错误信息
MyChatServer.disconnect(this); //断开连接
MyChatServer.notifyChatRoom(); //更新信息
return;}
……
3.2 客户端程序编写
提供良好的用户界面,便于用户连接、查看在线用户、发送信息。当与服务器建立连接后,发送聊天信息。同时,检测服务器端有无数据发送,接收数据,更新显示。
(1)界面设计(代码略)
(2)事件处理
建立连接的事件处理代码:
try{if (socket==null){
socket= new Socket(InetAddress.getLocalHost(),5656); //实例化一个套接字
ps=new PrintStream(socket.getOutputStream());//获取输出流
StringBuffer info=new StringBuffer("INFO: ");
String userinfo=jTextField1.getText()+":"+InetAddress.getLocalHost().toString();
ps.println(info.append(userinfo)); //输出信息
ps.flush();
listen=new Listen(this,jTextField1.getText(),socket); //实例化监听线程
listen.start(); /启动线程
}}catch (Exception ex){}
发送信息的代码:
if(socket!=null){StringBuffer msg=new StringBuffer("MSG: ");
String msgtxt=new String(jTextField2.getText());
ps.println(msg.append(jTextField2.getText())); //发送信息
ps.flush();
(3)监听线程的实现
Listen类用于与服务器进行通信,并维护一些连接信息。部分代码如下。
public Listen(MyChatClient p,String n,Socket s) {
……
public void run(){
String msg=null;
while(socket!=null){
try{msg=reader.readLine();//读取服务器端传来信息
}catch(IOException ex){
client.disconnect(); //出错则断开连接
}if (msg==null) { /从服务器传来的信息为空则断开此次连接
client.listen=null;
client.socket=null;
client.list1.removeAll();
return;}……}}
3.3 运行结果
本程序的运行界面如图3所示。
4 结束语
Java语言具有平台独立、面向对象、多线程、简单性、解释性等许多优点,是目前广泛流行的编程语言。笔者使用Socket与多线程机制相结合的方法,编写了简便的客户端与服务器的并发通信聊天程序。此程序具有成本低、节省带宽和跨平台可移植性的优点。随着宽带网络的进一步发展,我们还可以开发基于Socket的多人视频聊天软件。
参考文献:
[1] 王静,曲凤娟.基于Socket的多用户并发通信的設计[J].福建电脑,2007(3):164.
[2] 袁海燕,王文涛.Java实用程序设计100例[M].北京:人民邮电出版社,2005:226-229.
[3] 陈更力,张青.基于Java Socket网络编程的一种新实现[J].电脑开发与应用,2006(6):13.
注:“本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。”
关键词:Java;Socket;多客户并发;网络通信
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)20-30253-03
Design & Implement of Chat System Based on Socket Multi-user Parallel Communication
MO Zu-qin, OUYANG Yan-jie, MA Kang
(Dept of Computer Eng, Shiyan Technical Institute Eng, Shiyan 442000, China)
Abstract: As internet technic and computer language develop, more and more programmers make use of Java to compile net programme. This paper introduces the mechanism of communications and using the combination of Java language, Socket API technic and the multithreading to implement chat system in which multi-user and server can communicate parallel.
key words: Java; Socket; multi-user send parallel; Net communication
1 引言
Java是一種可以编写跨平台应用软件的面向对象的程序设计语言,网络应用是Java语言取得成功的领域之一,它已经成为现在Internet上最流行的一种编程语言。网络编程的目的就是直接或间接地通过网络协议与其它计算机进行通讯。两台计算机通讯需解决两个主要问题:一是如何准确定位网络上的主机;二是找到主机后如何可靠有效地进行数据传输。
Java语言作为网络编程语言,提供了强大的网络编程接口。针对网络通信的不同层次,Java提供的网络功能有四大类:InetAddress、URL、Socket、Datagram。Socket是Internet使用的协议组TCP/IP的组合,实现了两台主机之间通过端口进行网络通信。Java.net包中提供Socket类,隐藏了Socket的实现细节,不需要开发者编写接口程序,而可以快速的实现网络的通信。[1]
2 Socket的通信
2.1 Socket通信机制
在Java中,可以使用两种Socket方式,即流式Socket和数据报式Socket。流式Socket提供了双向的、有序的、无重复、可靠的的数据流服务,采用的是一种TCP协议。数据报式Socket支持双向的数据流,但不保证是可靠的、有序的、无重复的传输,采用的是UDP协议。[1]两种Socket相比较而言,流式Socket具有较高的安全性,但有一定的额外开销。而数据报式Socket与之相反。笔者根据实际情况采用的是流式Socket方式。
基于TCP协议的流式Socket实现网络通信的类有两个:在客户端的Socket类和在服务器端的ServerSocket类。无论一个Socket通信程序的功能多么齐全,程序多么复杂,Socket基本
结构都是一样的,都包括以下四个基本步骤:
(1)在客户端和服务器端创建Socket和ServerSocket实例;
(2)打开连接到Socket的输入/输出流;
(3)利用输入/输出流,按照一定的协议对Socket进行读/写操作;
(4)关闭输入/输出流和Socket。
Socket通信机制框图见图1。
2.2 Socket的多客户端并发通信
支持多个客户端的Socket通信实现方法有多种:方法一,在一台计算机上一次启动多个服务器程序(端口号必须不同);方法二,将服务器程序写成多线程的,不同处理线程为不同的客户服务,主线程只负责循环等待,处理线程负责网络连接,接收客户输入的信息。
实现多个客户与服务器并发通信,就像服务器与自己连接一样,笔者认为最好引入多线程机制。多线程正好是Java提供的一个重要机制,支持多个程序并发执行。服务器端每当建立一个新的Socket连接,主线程就启动一个新的线程,负责服务器与客户端的通信;而主线程继续等待下一个客户端的连接。当客户端断开连接后,子线程释放其占用的所有Socket资源[3]。多线程支持多客户端的具体框图见图2。
3 多客户端聊天程序的设计
系统主要分为两大部分:TCP服务器Server和客户端Client。
3.1 服务器端程序编写
服务器端等待用户连接,如有用户发送连接请求后,创建一个用户实例,记录客户端的相关信息,维护与该用户的连接。根据聊天的接收人信息,再将接收的数据传输给客户端。当用户断开连接时,关闭用户实例,断开此用户连接。[2]主要步骤如下:
(1) 启动服务器
try {
server=new ServerSocket(port);//初始化服务器套接字
while(true){socket=server.accept(); //等待客户连接
System.err.println(socket.getInetAddress()+"连接\n"); //得到客户机地址
Client client=new Client(socket);//实例化一个客户线程
clients.addElement(client);//增加客户线程到向量中
client.start(); //启动线程
notifyChatRoom(); //监视聊天室连接变化
} }catch(Exception ex) {
ex.printStackTrace(); //输出出错信息}
(2) 更新在线用户
for(int i=0;i
Client c=(Client)clients.elementAt(i);
newUser.append(":"+c.name);//客户端姓名字符串,取得客户端的名字
}sendClients(newUser); //把取得的客户端名字发送给每个客户端
(3) 多线程的实现
聊天室的服务器采用多线程实现,每当一个新的用户连接到服务器时,就实例化一个新的线程来与该客户端通信。Client类负责维护客户端的相关信息,比如IP地址、聊天室中的用户名、连接端口等,并实现了信息发送的send方法。主要代码如下。
//得到输入流
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintStream ps=new PrintStream(s.getOutputStream()); //得到输出流
String info=reader.readLine(); //读取接受到的信息
ps.println(msg); //输出信息
ps.flush();
public void run(){while(true){
String line=null;
try{line=reader.readLine();//读取数据流
}catch(IOException ex){
ex.printStackTrace(); //输出错误信息
MyChatServer.disconnect(this); //断开连接
MyChatServer.notifyChatRoom(); //更新信息
return;}
……
3.2 客户端程序编写
提供良好的用户界面,便于用户连接、查看在线用户、发送信息。当与服务器建立连接后,发送聊天信息。同时,检测服务器端有无数据发送,接收数据,更新显示。
(1)界面设计(代码略)
(2)事件处理
建立连接的事件处理代码:
try{if (socket==null){
socket= new Socket(InetAddress.getLocalHost(),5656); //实例化一个套接字
ps=new PrintStream(socket.getOutputStream());//获取输出流
StringBuffer info=new StringBuffer("INFO: ");
String userinfo=jTextField1.getText()+":"+InetAddress.getLocalHost().toString();
ps.println(info.append(userinfo)); //输出信息
ps.flush();
listen=new Listen(this,jTextField1.getText(),socket); //实例化监听线程
listen.start(); /启动线程
}}catch (Exception ex){}
发送信息的代码:
if(socket!=null){StringBuffer msg=new StringBuffer("MSG: ");
String msgtxt=new String(jTextField2.getText());
ps.println(msg.append(jTextField2.getText())); //发送信息
ps.flush();
(3)监听线程的实现
Listen类用于与服务器进行通信,并维护一些连接信息。部分代码如下。
public Listen(MyChatClient p,String n,Socket s) {
……
public void run(){
String msg=null;
while(socket!=null){
try{msg=reader.readLine();//读取服务器端传来信息
}catch(IOException ex){
client.disconnect(); //出错则断开连接
}if (msg==null) { /从服务器传来的信息为空则断开此次连接
client.listen=null;
client.socket=null;
client.list1.removeAll();
return;}……}}
3.3 运行结果
本程序的运行界面如图3所示。
4 结束语
Java语言具有平台独立、面向对象、多线程、简单性、解释性等许多优点,是目前广泛流行的编程语言。笔者使用Socket与多线程机制相结合的方法,编写了简便的客户端与服务器的并发通信聊天程序。此程序具有成本低、节省带宽和跨平台可移植性的优点。随着宽带网络的进一步发展,我们还可以开发基于Socket的多人视频聊天软件。
参考文献:
[1] 王静,曲凤娟.基于Socket的多用户并发通信的設计[J].福建电脑,2007(3):164.
[2] 袁海燕,王文涛.Java实用程序设计100例[M].北京:人民邮电出版社,2005:226-229.
[3] 陈更力,张青.基于Java Socket网络编程的一种新实现[J].电脑开发与应用,2006(6):13.
注:“本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。”