首页 > 编程 > Java > 正文

Java编程Socket实现多个客户端连接同一个服务端代码

2019-11-26 10:52:19
字体:
来源:转载
供稿:网友

Java Socket(套接字)通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

使用Socket实现多个客户端和同一客户端通讯;首先客户端连接服务端发送一条消息,服务端接收到消息后进行处理,完成后再回复客户端一条消息。本人通过自己的思维编写了一份服务端和客户端实现的代码,望能与大家相互学习,共同进步。

服务端代码

/** * Socket服务端 * 功能说明: *  */public class Server {	/**   * 入口   *    * @param args   * @throws IOException   */	public static void main(String[] args) throws IOException {		// 为了简单起见,所有的异常信息都往外抛		int port = 8899;		// 定义一个ServiceSocket监听在端口8899上		ServerSocket server = new ServerSocket(port);		System.out.println("等待与客户端建立连接...");		while (true) {			// server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的			Socket socket = server.accept();			/**       * 我们的服务端处理客户端的连接请求是同步进行的, 每次接收到来自客户端的连接请求后,       * 都要先跟当前的客户端通信完之后才能再处理下一个连接请求。 这在并发比较多的情况下会严重影响程序的性能,       * 为此,我们可以把它改为如下这种异步处理与客户端通信的方式       */			// 每接收到一个Socket就建立一个新的线程来处理它			new Thread(new Task(socket)).start();		}		// server.close();	}	/**   * 处理Socket请求的线程类   */	static class Task implements Runnable {		private Socket socket;		/**     * 构造函数     */		public Task(Socket socket) {			this.socket = socket;		}		@Override		    public void run() {			try {				handlerSocket();			}			catch (Exception e) {				e.printStackTrace();			}		}		/**     * 跟客户端Socket进行通信     *      * @throws IOException     */		private void handlerSocket() throws Exception {			// 跟客户端建立好连接之后,我们就可以获取socket的InputStream,并从中读取客户端发过来的信息了			/**       * 在从Socket的InputStream中接收数据时,像上面那样一点点的读就太复杂了,       * 有时候我们就会换成使用BufferedReader来一次读一行       *        * BufferedReader的readLine方法是一次读一行的,这个方法是阻塞的,直到它读到了一行数据为止程序才会继续往下执行,       * 那么readLine什么时候才会读到一行呢?直到程序遇到了换行符或者是对应流的结束符readLine方法才会认为读到了一行,       * 才会结束其阻塞,让程序继续往下执行。       * 所以我们在使用BufferedReader的readLine读取数据的时候一定要记得在对应的输出流里面一定要写入换行符(       * 流结束之后会自动标记为结束,readLine可以识别),写入换行符之后一定记得如果输出流不是马上关闭的情况下记得flush一下,       * 这样数据才会真正的从缓冲区里面写入。       */			BufferedReader br = new BufferedReader(			          new InputStreamReader(socket.getInputStream(), "UTF-8"));			StringBuilder sb = new StringBuilder();			String temp;			int index;			while ((temp = br.readLine()) != null) {				if ((index = temp.indexOf("eof")) != -1) {					// 遇到eof时就结束接收					sb.append(temp.substring(0, index));					break;				}				sb.append(temp);			}			System.out.println("Form Cliect[port:" + socket.getPort()			          + "] 消息内容:" + sb.toString());			// 回应一下客户端			Writer writer = new OutputStreamWriter(socket.getOutputStream(),			          "UTF-8");			writer.write(String.format("Hi,%d.天朗气清,惠风和畅!", socket.getPort()));			writer.flush();			writer.close();			System.out.println(			          "To Cliect[port:" + socket.getPort() + "] 回复客户端的消息发送成功");			br.close();			socket.close();		}	}}

客户端代码

import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.Reader;import java.io.Writer;import java.net.Socket;/** * Socket客户端* 功能说明: * * @author 大智若愚的小懂 * @Date 2016年8月30日 * @version 1.0 */public class Client {	/** * 入口 * @param args */	public static void main(String[] args) {		// 开启三个客户端,一个线程代表一个客户端 		for (int i = 0; i < 3; i++) {			new Thread(new Runnable() {				@Override public void run() {					try {						TestClient client = TestClientFactory.createClient();						client.send(String.format("Hello,Server!I'm %d.这周末天气如何。", client.client.getLocalPort()));						client.receive();					}					catch (Exception e) {						e.printStackTrace();					}				}			}			).start();		}	}	/** * 生产测试客户端的工厂 */	static class TestClientFactory {		public static TestClient createClient() throws Exception {			return new TestClient("127.0.0.1", 8899);		}	}	/** * 测试客户端 */	static class TestClient {		/** * 构造函数 * @param host 要连接的服务端IP地址 * @param port 要连接的服务端对应的监听端口 * @throws Exception */		public TestClient(String host, int port) throws Exception {			// 与服务端建立连接 			this.client = new Socket(host, port);			System.out.println("Cliect[port:" + client.getLocalPort() + "] 与服务端建立连接...");		}		private Socket client;		private Writer writer;		/** * 发送消息 * @param msg * @throws Exception */		public void send(String msg) throws Exception {			// 建立连接后就可以往服务端写数据了 			if(writer == null) {				writer = new OutputStreamWriter(client.getOutputStream(), "UTF-8");			}			writer.write(msg);			writer.write("eof/n");			writer.flush();			// 写完后要记得flush 			System.out.println("Cliect[port:" + client.getLocalPort() + "] 消息发送成功");		}		/** * 接收消息 * @throws Exception */		public void receive() throws Exception {			// 写完以后进行读操作 			Reader reader = new InputStreamReader(client.getInputStream(), "UTF-8");			// 设置接收数据超时间为10秒 			client.setSoTimeout(10*1000);			char[] chars = new char[64];			int len;			StringBuilder sb = new StringBuilder();			while ((len = reader.read(chars)) != -1) {				sb.append(new String(chars, 0, len));			}			System.out.println("Cliect[port:" + client.getLocalPort() + "] 消息收到了,内容:" + sb.toString());			reader.close();			// 关闭连接 			writer.close();			client.close();		}	}}

接下来模拟一下:

1.首先运行服务端

2.接着运行客户端(开三个客户端请求)

为了演示有所区分,服务端我使用的是Eclipse工具,客户端使用的是IntelliJ IDEA工具。这时可以看到客户端在控制台打印出来的消息

一个Port端口号代表一个客户端,回过来看下服务端在控制台打印出来的消息

总结

以上就是本文关于Java编程Socket实现多个客户端连接同一个服务端代码的全部内容,希望对大家有所帮助。有问题可以留言,小编会及时回复大家的。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表