http://blog.csdn.net/zhqingyun163/article/details/7991389
一直做Java web,几乎没有做过CS方向上的东西。最近一同学来北京找工作,到我这儿来玩。说起笔试经历,说了这样一个程序题,大概是这样的;
用C++编程实现一个简单的通信实例,要求服务器实时接受客户端发送来的消息。虽说没做过这方面的东西,但也知道需要用Java Socket来实现(坦白说C++不会)。工作之余花了2个小时写了一个基本满足要求的实例。也确实遇到了一些问题,贴出来,共同学习。
先贴代码。服务器端:
- package qy.server;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- public class MyServer {
- private ServerSocket serverSocket; //
- private ExecutorService servicePool; // 线程池
- public MyServer(int port) {
- try {
- this.serverSocket = new ServerSocket(port);
- this.servicePool = Executors.newFixedThreadPool(5);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public static void main(String[] args) {
- new MyServer(6666).service();
- }
- public void service() {
- int i = 0;
- while (true) {
- try {
- Socket socket = this.serverSocket.accept(); // 接受到一个连接,并且返回一个客户端的Socket对象实例
- this.servicePool.execute(new Handler(socket));
- System.out
- .println("User " + i + " is connecting to the Server");
- i++;
- } catch (IOException e) {
- e.printStackTrace();
- this.servicePool.shutdown();
- }
- }
- }
- class Handler implements Runnable {
- private Socket socket;
- public Handler(Socket socket) {
- this.socket = socket;
- }
- @Override
- public void run() {
- try {
- // 一个输入流,用于获取客户端传来的内容
- DataInputStream dis = new DataInputStream(
- this.socket.getInputStream());
- // 用于产生服务器准备响应的内容
- DataOutputStream dos = new DataOutputStream(this.socket.getOutputStream());
- String str;
- while (null != (str = dis.readUTF())) {
- System.out.println(str);
- if ("exit".equals(str)) {
- System.out.println("客户端发出中断请求");
- dos.writeUTF("服务器已经关闭本次连接.");
- dos.flush();
- // dos.writeUTF("exit"); //
- // dos.flush();
- dos.close();
- dis.close();
- break;
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- package qy.client;
- import java.io.BufferedReader;
- import java.io.DataInputStream;
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.Socket;
- public class MyClient {
- public static void main(String[] args) {
- try {
- Socket client = new Socket("localhost", 6666);
- MyClient me = new MyClient();
- new Thread(me.new Handler(client)).start();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- class Handler implements Runnable {
- private BufferedReader br;
- private DataOutputStream dos;
- private DataInputStream dis;
- private Socket socket;
- private boolean flag = true; // 用于控制循环结束
- public Handler(Socket s) throws IOException {
- this.br = new BufferedReader(new InputStreamReader(System.in)); // 用于从控制台接受输入的信息,再发送到服务器
- this.socket = s;
- this.dos = new DataOutputStream(this.socket.getOutputStream()); // 向服务器写数据的输出流
- this.dis = new DataInputStream(this.socket.getInputStream()); // 获取服务器返回数据的输入流
- }
- @Override
- public void run() {
- while (flag) {
- try {
- String str = br.readLine();
- if ("exit".equals(str)) { // 客户端终止发送信息标记 exit
- this.br.close();
- this.dos.writeUTF(str);
- this.dos.flush();
- String res = dis.readUTF();
- System.out.println(res);
- this.dis.close();
- this.dos.close();
- this.flag = false;
- } else {
- this.dos.writeUTF(str);// 每读一行就发送一行
- this.dos.flush();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
- }
遇到的问题:
最先考虑的是使用BufferedReader和BufferedWriter来完成双向数据的写入写出,但是发现BufferedWriter在fush()的时候并不能把从控制台得到的数据立即发送到服务端,就改用DataOutputStream数据流来完成双向数据传递。