Java Socket实现多个客户端连接同一个服务端

原创 2016年08月30日 18:16:17

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


  服务端代码

/**
 * Socket服务端<br>
 * 功能说明:
 * 
 * @author 大智若愚的小懂
 * @Date 2016年8月30日
 * @version 1.0
 */
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();
		}

	}

}



  客户端代码

<pre name="code" class="java">import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.Socket;

/**
 * Socket客户端<br>
 * 功能说明:
 *
 * @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 服务器和客户端通信的例子

一个 HelloWord 级别的 Java Socket 通信的例子。通讯过程:         先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求。然后运行 Client 端...
  • defonds
  • defonds
  • 2012年09月12日 15:21
  • 138659

Java Socket多线程服务端、客户端

Java Socket多线程服务端、客户端 分类: JAVA 2011-11-08 22:49 87人阅读 评论(0) 收藏 举报 view plain ...
  • m13666368773
  • m13666368773
  • 2011年11月17日 10:14
  • 8554

java socket服务器与客户端的通信实现用户登录

  • 2009年11月22日 11:36
  • 109KB
  • 下载

java socket长连接服务端

java socket长连接服务端的实现 网络编程都是最底层都是基于socket的,鉴于客户端需要一直发送消息,使用短连接就不适合了,因为建立socket连接后发送完数据又马上断开连接。而长连接通...
  • u013144287
  • u013144287
  • 2017年08月03日 23:06
  • 1901

java网络socket编程(三)之ServerSocket服务器端

一、简介 java提供了一个ServerSocket类表示服务器Socket。服务器Socket在服务器上运行,监听入站ftp连接。每个服务器Socket监听服务器上的一个特定端口。当远程注解上的一个...
  • zzjstudent
  • zzjstudent
  • 2016年07月13日 18:43
  • 5467

JAVA编写的一个简单的Socket实现的HTTP响应服务器进阶版

1、首先建立ServerSocket监听8000端口,等待浏览器的连接。 public class HttpServer { //WEB_ROOT该服务器的根目录,这个目录可以自己定义,主要是服务...
  • u012945986
  • u012945986
  • 2016年09月20日 17:16
  • 1762

java实现websocket客户端与服务端的连接

  • 2017年08月15日 15:16
  • 2.48MB
  • 下载

Java Socket 简单的Client/Server程序

一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输。 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地...
  • cynhafa
  • cynhafa
  • 2011年10月14日 14:53
  • 39161

Java Websocket实例【服务端与客户端实现全双工通讯】

Java Websocket实例【服务端与客户端实现全双工通讯】 现很多网站为了实现即时通讯,所用的技术都是轮询(polling)。轮询是在特定的的时间间隔(如每1秒),由浏览器...
  • u013490585
  • u013490585
  • 2017年07月27日 10:14
  • 2320

Java客户端C++服务端Socket交互通信

原文地址:http://www.drdobbs.com/jvm/java-and-c-socket-communication/222900697?pgno=1 通过socket网络通信集成c++ ...
  • hnyzwtf
  • hnyzwtf
  • 2016年03月20日 21:48
  • 5904
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java Socket实现多个客户端连接同一个服务端
举报原因:
原因补充:

(最多只允许输入30个字)