聊天软件客户端
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://sophi.blog.51cto.com/340461/66381 |
import java.net.*; import java.io.*; public class Client { /////////////Control + C 时发生NullPointerException,在写线程处 public static void main(String[] args) { // 获取客户端名字 Client.cname = args[0]; // 获取服务器IP地址 Client.hostIP = args[1]; // 启动客户端 new Client().start(); } /* * 客户端启动函数 */ public void start() { // 客户端与服务器建立连接 connect(); // 为已连接的Socket准备好输入输出流 prepareIO(); // 客户端向服务器注册自己的身份 login(); // 启动客户端的消息接受线程 cr = new Thread(new ClientReadMessage()); cr.start(); // 启动客户端的消息输出线程 cw = new Thread(new ClientWriteMessage()); cw.start(); } /* * 连接到指定的服务器 */ public void connect() { try { client = new Socket(hostIP, 8888); connected = true; } catch (UnknownHostException e) { System.out.println("服务器不存在或者已经关闭!"); System.exit(-1); } catch (IOException e) { System.out.println("服务器已经关闭"); System.exit(-1); } } /* * 断开与服务器的连接 */ public void disconnect() { try { connected = false; sendMessage("?bye");//通知服务器客户端要关闭,让服务器自己先把IO流关闭 if (din != null) din.close(); if (dout != null) dout.close(); if (br != null) dout.close(); if (client != null) client.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println("You 退出了!"); } /* * 客户端注册函数 */ public void login() { sendMessage(cname); } /* * 输入输出流生成函数 包括一个标准输入流、一个Socket输出流和一个Socket输入流 */ public void prepareIO() { br = new BufferedReader(new InputStreamReader(System.in)); try { dout = new DataOutputStream(client.getOutputStream()); din = new DataInputStream(client.getInputStream()); } catch (IOException e) { e.printStackTrace(); } } /* * 客户端发送信息线程类 从控制台输入信息,并发送到服务器 */ class ClientWriteMessage implements Runnable { @Override public void run() { String str = null; while (connected) { str = receiveConsole(); if (str.equals("?bye")) { disconnect(); } else { sendMessage(str); } } } } /* * 客户端接受信息线程类 从服务器接受信息,并在控制台显示 */ class ClientReadMessage implements Runnable { @Override public void run() { while (connected) { String str = receiveMessage(); System.out.println(str); } } } /* * 消息输出函数 向服务器发送消息 */ public void sendMessage(String message) { try { dout.writeUTF(message); dout.flush(); } catch (IOException e) { e.printStackTrace(); } } /* * 消息输入函数 从服务器接受消息 */ public String receiveMessage() { String message = null; try { message = din.readUTF(); } catch (EOFException e) {//////////第二条开始发送?bye时连续发生异常,其实也是服务器的socket关闭 message = ""; System.exit(0); } catch (SocketException e) {///////第一条发送?bye发生异常,因为服务器的socket已经关闭 message = ""; System.exit(0); } catch (IOException e) { e.printStackTrace(); } return message; } /* * 消息输入函数 从控制台接受输入 */ public String receiveConsole() { String message = null; try { message = br.readLine(); } catch (IOException e) { e.printStackTrace(); } return message; } Socket client = null; static String cname = null; static String hostIP = null; volatile boolean connected = false; Thread cr = null; Thread cw = null; BufferedReader br = null; DataOutputStream dout = null; DataInputStream din = null; } 本文出自 ““技”忆” 博客,请务必保留此出处http://sophi.blog.51cto.com/340461/66381 本文出自 51CTO.COM技术博客 |


huixianmaomao
博客统计信息
热门文章
最新评论
友情链接