java Socket通信实例

一直做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数据流来完成双向数据传递。




你可能感兴趣的:(java,thread,String,socket,服务器,Class)