Java Socket编程实现在终端上的双工Chat
2015-06-08 20:44
411 查看
理应是对等通信,不过Java Socket通信总要区分Server和Client。但Socket有
和
因而,我们可以用两个线程分别做输入(听)和输出(说)两件事,这样我们就可以在一个终端上既能输入数据也能显示对方发送过来的数据了。这篇文章的代码已经非常简明,我在实现自己代码的过程中向这篇文章学习了很多,完全可以只读这篇文章。
在ChatServer的main方法里开启这两个线程。需要注意的是,ChatServer需要给定port,ChatClient需要指定server的地址和相同的port。例如在同一局域网内,我在主机A(Server,IP地址是192.168.1.142)的终端运行:
开启服务器端的两个进程。然后在主机B(Client)的终端运行:
之后,就可以在这两个终端上你来我往聊天了。但是有一个问题,Server不能被多次连接,这不合理,合理的应该是这样:当Client主动断开之后,Server端程序不会退出,且在Client再次连接时,两台主机又能双工通信了。目前,当Server端退出之后,再连接Server,两个终端并不能即时通信了。
接着用
不断读入控制台数据。
贴代码
public InputStream getInputStream() throws IOException
和
public OutputStream getOutputStream() throws IOException
因而,我们可以用两个线程分别做输入(听)和输出(说)两件事,这样我们就可以在一个终端上既能输入数据也能显示对方发送过来的数据了。这篇文章的代码已经非常简明,我在实现自己代码的过程中向这篇文章学习了很多,完全可以只读这篇文章。
设计
为Server端和Client端分别实现两个继承Thread类的类,分别执行听和说两个任务。当开启Server端和Client端时,就开始这两个线程。例如在Server端的ChatServer.java中,我写了class ServerReadingThread extends Thread class ServerWritingThread extends Thread public class ChatServer
在ChatServer的main方法里开启这两个线程。需要注意的是,ChatServer需要给定port,ChatClient需要指定server的地址和相同的port。例如在同一局域网内,我在主机A(Server,IP地址是192.168.1.142)的终端运行:
java ChatServer 6066
开启服务器端的两个进程。然后在主机B(Client)的终端运行:
java ChatClient 192.168.1.142 6066
之后,就可以在这两个终端上你来我往聊天了。但是有一个问题,Server不能被多次连接,这不合理,合理的应该是这样:当Client主动断开之后,Server端程序不会退出,且在Client再次连接时,两台主机又能双工通信了。目前,当Server端退出之后,再连接Server,两个终端并不能即时通信了。
从控制台读取字符串:
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in());
接着用
bf.readLine();
不断读入控制台数据。
Socket文件流
使用DataInputStream和DataOutputStream类来处理,从DataInputStream对象读入时使用它的readUTF()方法,向DataOutputStream对象写字符串时使用它的writeUTF(str)方法。贴代码
ChatServer.java
import java.net.*; import java.io.*; class ServerReadingThread extends Thread { private DataInputStream in; public ServerReadingThread(DataInputStream in) { this.in = in; } public void run() { try { String str; do { str = in.readUTF(); if(str.equals("end")) System.exit(0); System.out.println(str); }while(!str.equals("end")); }catch(IOException e) { e.printStackTrace(); } } } class ServerWritingThread extends Thread { private DataOutputStream out; public ServerWritingThread(DataOutputStream out) { this.out = out; } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; do { str = br.readLine(); out.writeUTF(str); if(str.equals("end")) System.exit(0); }while(!str.equals("end")); }catch(IOException e) { e.printStackTrace(); } } } public class ChatServer { public static void main(String [] args) { int port = Integer.parseInt(args[0]); try { ServerSocket serverSocket = new ServerSocket(port); Socket server = serverSocket.accept(); DataInputStream in = new DataInputStream(server.getInputStream()); DataOutputStream out = new DataOutputStream(server.getOutputStream()); Thread listen = new ServerReadingThread(in); Thread speak = new ServerWritingThread(out); System.out.println("Enter 'end' to exit."); listen.start(); speak.start(); }catch(IOException e) { e.printStackTrace(); } } }
ChatClient.java
import java.net.*; import java.io.*; class ClientReadingThread extends Thread { private DataInputStream in; public ClientReadingThread(DataInputStream in) { this.in = in; } public void run() { try { String str; do { str = in.readUTF(); if (str.equals("end")) System.exit(0); System.out.println(str); }while(!str.equals("end")); }catch(IOException e) { e.printStackTrace(); } } } class ClientWritingThread extends Thread { private DataOutputStream out; public ClientWritingThread(DataOutputStream out) { this.out = out; } public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str; do { str = br.readLine(); out.writeUTF(str); if (str.equals("end")) System.exit(0); }while(!str.equals("end")); }catch(IOException e) { e.printStackTrace(); } } } public class ChatClient { public static void main(String [] args) { String serverName = args[0]; int port = Integer.parseInt(args[1]); try { Socket client = new Socket(serverName, port); DataInputStream in = new DataInputStream(client.getInputStream()); DataOutputStream out = new DataOutputStream(client.getOutputStream()); Thread listen = new ClientReadingThread(in); Thread speak = new ClientWritingThread(out); System.out.println("Enter 'end' to exit!"); listen.start(); speak.start(); }catch(IOException e) { e.printStackTrace(); } } }
相关文章推荐
- Android NDK(学习笔记三)—— 配置Eclipse自动进行ndk-build
- Java技术路线图
- java有没有goto
- java读取TXT文件的方法 (转)
- myeclipse去掉maven项目红叉的方法
- java实现各种排序算法及比较
- java内存泄漏
- Spring 加载类路径外的资源文件
- eclipse在debug模式下鼠标移动到变量上不显示值的问题
- 【转】java中static{}语句块详解
- [Drools]JAVA规则引擎 -- Drools
- jdk6,jdk7直链下载方法
- spring整合消息队列rabbitmq
- RxJava的Subscriber出现onError时
- Java语言描述:动态规划法之编辑距离问题
- 使用Spring集成Hibernate配置,根据实体类自动创建表
- Java在继承中构造器的调用顺序
- Java设计模式---观察者模式
- Java-插入排序
- Java虚拟机之自定义类加载器