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端口号代表一个客户端,回过来看下服务端在控制台打印出来的消息



版权声明:原创文章,转载时请务必以超链接形式标明文章原始出处 、作者信息,否则将追究法律责任。

相关文章推荐

socket实现多个客户端连接在一个服务器上

1、使用socekt通信一般步骤     1)服务器端:socker()建立套接字,绑定(bind)并监听(listen),用accept()等待客户端连接。     2)客户端:socker()...

Windows Socket 编程_单个服务器对多个客户端简单通讯

单个服务器对多个客户端程序: 一。简要说明 二。查看效果 三。编写思路 四。程序源代码 五。存在问题   一。简要说明:  程序名为:TcpSocketOneServerToMulCl...
  • neicole
  • neicole
  • 2012年05月06日 14:49
  • 13327

C# Sockets实现服务器与多个客户端进行通讯

学习一个新的东西,首先要知道其原理,对于Sockets的学习,可先看一下文档:http://blog.csdn.net/hulihui/article/details/3230503#st     点...

C++ Socket网络通信实现一个服务器端和多个客户端的通信

一 描述 1 采用C++语言 2 编译环境是code::blocks 3 使用的是非阻塞套接字 二 功能描述 1 一个服务器对多个客户端 2 服务器端主要负责处理数据的输入并发送,具体是通过发送指令...

C++ Socket 一个服务器 多个客户端 (阻塞式)

服务端 ServerNet.h#pragma once #include #include #include #include #include #include #include #incl...

linux下socket编程实现一个服务器连接多个客户端

使用socekt通信一般步骤     1)服务器端:socker()建立套接字,绑定(bind)并监听(listen),用accept()等待客户端连接。     2)客户端:socker()建立...

Java Socket(六) 使用多线程实现多客户端的通信

问题一个服务端可以跟多个客户端通讯基本步骤1.服务器端创建ServerSocket方法,循环调用accept()方法等待客户端连接2.客户端创建socket和服务的请求连接3.服务端接受客户端的请求,...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

JAVA SOCKET网络编程,服务端接收多个客户端连接的实现

这是基于前面一篇文章的一个简单扩展,当然这不是最好的实现 服务端如果要想接收多个客户端连接,必须...

一个 Java 的 Socket 服务器和客户端通信的例子

一个 HelloWord 级别的 Java Socket 通信的例子。通讯过程:         先启动 Server 端,进入一个死循环以便一直监听某端口是否有连接请求。然后运行 Client 端...
  • defonds
  • defonds
  • 2012年09月12日 15:21
  • 126132
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java Socket实现多个客户端连接同一个服务端
举报原因:
原因补充:

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