源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

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

  • 时间:2020-05-29 23:00 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要: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.首先运行服务端 [img]http://files.jb51.net/file_images/article/201711/20171122142046288.png?2017102214212[/img] 2.接着运行客户端(开三个客户端请求) 为了演示有所区分,服务端我使用的是Eclipse工具,客户端使用的是IntelliJ IDEA工具。这时可以看到客户端在控制台打印出来的消息 [img]http://files.jb51.net/file_images/article/201711/20171122142220804.png?20171022142232[/img] 一个Port端口号代表一个客户端,回过来看下服务端在控制台打印出来的消息 [img]http://files.jb51.net/file_images/article/201711/20171122142307355.png?20171022142318[/img] [b]总结[/b] 以上就是本文关于Java编程Socket实现多个客户端连接同一个服务端代码的全部内容,希望对大家有所帮助。有问题可以留言,小编会及时回复大家的。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部