您的位置:首页 > 理论基础 > 计算机网络

JavaSE_基于TCP协议的Socket实现的控制台聊天程序

2017-09-11 17:50 841 查看
一个小的Demo, 可以运用监视器模式扩展成带广播与私聊的聊天小程序,这里不做演示。记录下自己学socket 的过程。Server 端:package com.test.socket;import java.io.*;import java.net.ServerSocket;import java.net.Socket;import java.util.Scanner;/*** Created by szh on 2017/9/10.*/public class SocketSingleServer extends Thread {public static Boolean exitSignal = false;InputStream inputStream = null;SocketSingleServer(InputStream stream) {this.inputStream = stream;this.start();}@Overridepublic void run() {try {RandomAccessFile accessFile = new RandomAccessFile("out/socketClientMessage.txt", "rw");accessFile.seek(accessFile.length());BufferedReader reader = new BufferedReader(new InputStreamReader(this.inputStream));String tmpLine = null;while(true){synchronized (SocketSingleServer.exitSignal){if(SocketSingleServer.exitSignal) break;while(reader.ready()){tmpLine = reader.readLine();accessFile.write((tmpLine+"\r\n").getBytes());System.out.println(tmpLine);}}}} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {ServerSocket serverSocket = null;Socket s = null;InputStream inputStream = null;OutputStream outputStream = null;PrintWriter writer = null;SocketSingleServer serverThread = null;try {serverSocket = new ServerSocket(8080);//会阻塞进程s = serverSocket.accept();if (s != null) {System.out.println("建立连接");inputStream = s.getInputStream();outputStream = s.getOutputStream();writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));serverThread = new SocketSingleServer(inputStream);Scanner scanner = new Scanner(System.in);String tmpLine = null;while (!(tmpLine = scanner.nextLine()).equals("exit")) {writer.println("Server Say : " + tmpLine);writer.flush();}// synchronized (SocketSingleServer.exitSignal){// SocketSingleServer.exitSignal = true;// }}} catch (Exception e) {e.printStackTrace();} finally {try {synchronized (SocketSingleServer.exitSignal){SocketSingleServer.exitSignal = true;s.shutdownInput();writer.close();outputStream.close();inputStream.close();s.close();}} catch (Exception e) {e.printStackTrace();}}}}Client 端:package com.test.socket;import java.io.*;import java.net.InetAddress;import java.net.Socket;import java.util.Scanner;/*** Created by szh on 2017/9/10.*/public class SocketSingleClient extends Thread {public static Boolean exitSignal = false;InputStream inputStream = null;SocketSingleClient(InputStream stream) {this.inputStream = stream;this.start();}@Overridepublic void run() {RandomAccessFile accessFile = null;BufferedReader reader = null;try {accessFile = new RandomAccessFile("out/socketServerMessage.txt", "rw");accessFile.seek(accessFile.length());reader = new BufferedReader(new InputStreamReader(this.inputStream));String tmpLine = null;while (true) {synchronized (SocketSingleClient.exitSignal) {if (SocketSingleClient.exitSignal) break;while (reader.ready()) {tmpLine = reader.readLine();accessFile.write((tmpLine+"\r\n").getBytes());System.out.println(tmpLine);}}}System.out.println("step2");} catch (Exception e) {e.printStackTrace();} finally {try {reader.close();accessFile.close();this.inputStream.close();} catch (Exception e) {e.printStackTrace();}}}public static void main(String[] args) throws Exception {Socket clientSocket = null;InputStream inputStream = null;OutputStream outputStream = null;PrintWriter writer = null;try {clientSocket = new Socket(InetAddress.getByAddress(new byte[]{127, 0, 0, 1}), 8080);inputStream = clientSocket.getInputStream();outputStream = clientSocket.getOutputStream();writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));//创建一个线程用于输出服务端的输入new SocketSingleClient(inputStream);Scanner scanner = new Scanner(System.in);String tmpLine = null;while (!(tmpLine = scanner.nextLine()).equals("exit")) {writer.println("Client Say : " + tmpLine);writer.flush();}synchronized (SocketSingleClient.exitSignal) {SocketSingleClient.exitSignal = true;}System.out.println("step1");} catch (Exception e) {e.printStackTrace();} finally {try {clientSocket.shutdownInput();writer.close();inputStream.close();outputStream.close();clientSocket.close();} catch (Exception e) {e.printStackTrace();}}}}
程序的主要思路是聊天程序中 读取对方的发送内容 / 写给对方内容  应该是可以并行执行的操作,故用了2个线程分别执行 读 与 写这里主要记录下为什么用到了 同步监视器由于最终的写入的socket 输入 exit, 线程退出并释放资源. 此时子线程传入的 InputStream 并不知道主线程结束了,再去调用readLine 会引发异常,崩溃退出,程序不够优雅。(readLine 会阻塞进程) 故加了一个状态位标识 socket 的状态,读取流 与 释放资源分别是 两块原子操作!!!!效果:123
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: