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

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实现多个客户端连接同一个服务端代码的全部内容,希望对大家有所帮助。有问题可以留言,小编会及时回复大家的。

(0)

相关推荐

  • 基于BIO的Java Socket通信详解

    BIO,即阻塞IO,在基于Socket的消息通信过程中,Socket服务端向外部提供服务,而Socket客户端可以建立到Socket服务端的连接,进而发送请求数据,然后等待Socket服务端处理,并返回处理结果(响应). 基于BIO的通信,Socket服务端会发生阻塞,即在监听过程中每次accept到一个客户端的Socket连接,就要处理这个请求,而此时其他连接过来的客户端只能阻塞等待.可见,这种模式下Socket服务端的处理能力是非常有限的,客户端也只能等待,直到服务端空闲时进行请求的处理.

  • Java Socket通信之聊天室功能

    本文实例为大家分享了Java Socket聊天室功能的具体代码,供大家参考,具体内容如下 Client.java import java.io.*; import java.net.*; import java.util.*; public class Client { public int port = 8083; Socket socket = null; public static void main(String[] args) { new Client(); //开始执行 } publ

  • Java Socket通信介绍及可能遇到的问题解决

    前言 本文主要给大家介绍了关于Java中Socket通信的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. Java中基于TCP协议实现网络通信的两个类:客户端的Socket和服务器端的ServerSocket. Socket通信模型如图所示: 不管Socket通信的功能有多复杂,任何socket通信过程的基本结构都是一样的. 其基本步骤为: ①分别在客户端和服务器端创建Socket和ServerSocket实例:服务器端通过.accept()方法等待请求并阻塞.请求收

  • Java编程利用socket多线程访问服务器文件代码示例

    这篇文章将向大家展示Java编程利用socket多线程访问服务器文件代码示例,如果您想先了解Java多线程socket编程的基础知识,可以看下这篇文章:Java多线程编程实现socket通信示例代码. 接下来进入正文,我们看看利用socket多线程访问服务器代码: ServerMain.java package com.ysk.webServer; import java.io.File; import java.io.IOException; import java.net.ServerSoc

  • Java多线程编程实现socket通信示例代码

    流传于网络上有关Java多线程通信的编程实例有很多,这一篇还算比较不错,代码可用.下面看看具体内容. TCP是Tranfer Control Protocol的 简称,是一种面向连接的保证可靠传输的协议.通过TCP协议传输,得到的是一个顺序的无差错的数据流.发送方和接收方的成对的两个socket之间必须建 立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是server socket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以

  • Java Socket编程服务器响应客户端实例代码

    通过输入流来读取客户端信息,相应的时候通过输出流来实现. 服务端类的代码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; impo

  • Java中Spring WebSocket详解

    首先 pom.xml <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> </parent> <dependency> <groupId>org.apache.com

  • Java Socket编程心跳包创建实例解析

    1.什么是心跳包? 心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包. 用来判断对方(设备,进程或其它网元)是否正常运行,采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经离线.用于检测TCP的异常断开.基本原因是服务器端不能有效的判断客户端是否在线,也就是说,服务器无法区分客户端是长时间在空闲,还是已经掉线的情况.所谓的心跳包就是客户端定时发送简单的信息给服务器端告诉它我还在而已.代码就是每隔几分

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

    Java Socket(套接字)通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 使用Socket实现多个客户端和同一客户端通讯:首先客户端连接服务端发送一条消息,服务端接收到消息后进行处理,完成后再回复客户端一条消息.本人通过自己的思维编写了一份服务端和客户端实现的代码,望能与大家相互学习,共同进步. 服务端代码 /** * Socket服务端 * 功能说明: * */ public cl

  • C#实现Socket服务器及多客户端连接的方式

    服务端代码[控制台示例] static List<Socket> Sockets = new List<Socket>(); static void Main(string[] args) { int port = 10; byte[] buffer = new byte[1024]; IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port); Socket listener = new Socket(localEP.Addr

  • Java编程之多线程死锁与线程间通信简单实现代码

    死锁定义 死锁是指两个或者多个线程被永久阻塞的一种局面,产生的前提是要有两个或两个以上的线程,并且来操作两个或者多个以上的共同资源:我的理解是用两个线程来举例,现有线程A和B同时操作两个共同资源a和b,A操作a的时候上锁LockA,继续执行的时候,A还需要LockB进行下面的操作,这个时候b资源在被B线程操作,刚好被上了锁LockB,假如此时线程B刚好释放了LockB则没有问题,但没有释放LockB锁的时候,线程A和B形成了对LockB锁资源的争夺,从而造成阻塞,形成死锁:具体其死锁代码如下:

  • Java编程通过list接口实现数据的增删改查代码示例

    List接口常用的实现ArrayList. 常用方法:add(Object obj)  增加一个元素                      add(int index,Object obj) 在指定索引位置添加元素                      remove(int index) 删除指定位置的元素                      remove(Objiect)  从列表中删除元素                      set(index,Object) 修改指定位

  • Java编程用栈来求解汉诺塔问题的代码实例(非递归)

    [题目] 汉诺塔问题比较经典,这里修改一下游戏规则:现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间.求当塔有N层的时候,打印最优移动过程和最优移动总步数. [解答] 上一篇用的是递归的方法解决这个问题,这里我们用栈来模拟汉诺塔的三个塔,也就是不用递归的方法 原理是这样的:修改后的汉诺塔问题不能让任何塔从左直接移动到右,也不能从右直接移动到左,而是要经过中间,也就是说,实际上能做的动作,只有四个:左->中,中->左,中->右,右->中 用栈

  • java编程实现杨辉三角两种输出结果实例代码

    首先展示下结果: 简介: 杨辉三角,是二项式系数在三角形中的一种几何排列.在欧洲,这个表叫做帕斯卡三角形.帕斯卡(1623----1662)是在1654年发现这一规律的,比杨辉要迟393年,比贾宪迟600年.杨辉三角是中国古代数学的杰出研究成果之一,它把二项式系数图形化,把组合数内在的一些代数性质直观地从图形中体现出来,是一种离散型的数与形的优美结合. 实例代码如下: package com.sxt; import java.util.Arrays; public class KeBen { p

  • Java编程实现计算两个日期的月份差实例代码

    本文实例主要实现计算两个日期的月份差,具体如下: package com.forezp.util; import org.joda.time.DateTime; import org.joda.time.Months; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; /** * 在JAVA中,如何计算两个日期的月份差?<br> * * * @author Adm

  • Java实现TCP/IP协议的收发数据(服务端)代码实例

    这篇文章主要介绍了Java实现TCP/IP协议的收发数据(服务端)代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 功能如下: 注: 只有服务端,没有客户端,测试时采用第三方软件作为客户端的. 收发数据目前能正常收发数据,只是中文的会变成乱码显示. 采用Thread类实现一个收发数据的线程. 服务端代码: import java.io.IOException; import java.io.InputStream; import java

  • javaweb启动时启动socket服务端代码实现

    这篇文章主要介绍了javaweb启动时启动socket服务端代码实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 说明:在javaweb项目启动的时候启动socket服务端,可以接受客户端发送过来的数据,客户端可以反复断开连接 1.新建SocketThread线程类 package com.wlw.modules.startImplement.web; import java.io.IOException; import java.net.S

  • Java面试Socket编程常用参数设置源码问题分析

    目录 引导语 1.Socket整体结构 2.初始化 3.connect连接服务端 4.Socket常用设置参数 4.1.setTcpNoDelay 4.2.setSoLinger 4.3.setOOBInline 4.4.setSoTimeout 4.5.setSendBufferSize 4.6.setReceiveBufferSize 4.7.setKeepAlive 4.8.setReuseAddress 5.总结 引导语 Socket 中文翻译叫套接字,可能很多工作四五年的同学都没有用过

随机推荐