欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-12-16 21:57:40
java socket(套接字)通常也称作"套接字",用于描述ip地址和端口,是一个通信链的句柄。应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 使用sock...

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.首先运行服务端

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

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

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

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

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

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

总结

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

上一篇:

下一篇: