java多客户端和单服务端

简介: java多客户端和单服务端

该例子可以实现多个客户端的聊天室功能,即任何一个客户端发送消息给服务器,服务器会转发给所有与它连接的客户端。因为服务器要维护与多个客户端的连接,这里用线程实现,每个客户端和服务器端连接后,服务器端都会开启一个线程,用于接收当前这个客户端的消息,并转发给所有的客户端。


该例子由3个Java类实现,客户端:tcp. EchoMultiClient,服务器端:tcp.

EchoMultiServer,tcp.EchoServerThread(服务器端使用的线程类)。


客户端类,该客户端发送消息和接收消息分别在一个线程中进行:



package test;
import java.util.List;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class MultiServer {
ServerSocket serverSocket;
List<Socket> clients=new ArrayList<Socket>();
public MultiServer() {
  try {
    serverSocket=new ServerSocket(7);
    while(true) {
      Socket clientSocket=serverSocket.accept();
      clients.add(clientSocket);
      new EchoServerThread(clientSocket,clients).start();
    }
  }catch(IOException e) {
    e.printStackTrace();
  }
}
public static void main(String[] args) {
  new MultiServer();
}
}


服务器端代码,该代码中每监听到客户端的一个连接,就调用线程类创建并启动一个线程对象。


服务器端代码:



package test;
import java.util.List;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class MultiServer {
ServerSocket serverSocket;
List<Socket> clients=new ArrayList<Socket>();
public MultiServer() {
  try {
    serverSocket=new ServerSocket(7);
    while(true) {
      Socket clientSocket=serverSocket.accept();
      clients.add(clientSocket);
      new EchoServerThread(clientSocket,clients).start();
    }
  }catch(IOException e) {
    e.printStackTrace();
  }
}
public static void main(String[] args) {
  new MultiServer();
}
}


服务器端使用的线程类代码:



package test;
//服务器端使用的线程类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.List;
public class EchoServerThread extends Thread{
Socket myClient;
List<Socket> clients;
String clientHostName;
int clientPort;
public EchoServerThread(Socket myClient,List<Socket> clients) {
  super();
  this.myClient=myClient;
  this.clients=clients;
}
public void run() {
  InetSocketAddress clientAddress=(InetSocketAddress)myClient.getRemoteSocketAddress();
  clientHostName=clientAddress.getHostName();
  clientPort=clientAddress.getPort();
  System.out.println("第"+clients.size()+"个客户端"+clientHostName+":"+clientPort+"已连接");
  try {
    String inStr;
    BufferedReader in=new BufferedReader(new InputStreamReader(myClient.getInputStream()));
    while((inStr=in.readLine())!=null) {
      System.out.println(inStr+".来自"+clientHostName+":"+clientPort+"");
      for(Socket client:clients) {
        if(client!=null) {
          PrintWriter out=new PrintWriter(client.getOutputStream(),true);
          out.println(inStr+".来自"+clientHostName+":"+clientPort+"");
        }
    }
} 
}catch(IOException e) {
  System.err.println(clientHostName+":"+clientPort+"退出了.");
}
}
}


该程序运行时,先启动服务器端代码,再多次启动客户端。


例如以下运行效果,启动了服务器端后,启动了3次客户端,3个客户端分别发送消息,效果如下:


效果图:


相关文章
|
1月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
41 4
|
2月前
|
JSON Java 开发工具
Java服务端集成Google FCM推送的注意事项和实际经验
本文分享了作者在公司APP海外发布过程中,选择Google FCM进行消息推送的集成经验。文章详细解析了Java集成FCM推送的多种实现方式,包括HTTP请求和SDK集成,并指出了通知栏消息和透传消息的区别与应用场景。同时,作者还探讨了Firebase项目的创建、配置和服务端集成的注意事项,帮助读者解决文档混乱和选择困难的问题。
66 1
|
3月前
|
JSON NoSQL Java
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
这篇文章介绍了在Java中使用Redis客户端的几种方法,包括Jedis、SpringDataRedis和SpringBoot整合Redis的操作。文章详细解释了Jedis的基本使用步骤,Jedis连接池的创建和使用,以及在SpringBoot项目中如何配置和使用RedisTemplate和StringRedisTemplate。此外,还探讨了RedisTemplate序列化的两种实践方案,包括默认的JDK序列化和自定义的JSON序列化,以及StringRedisTemplate的使用,它要求键和值都必须是String类型。
redis的java客户端的使用(Jedis、SpringDataRedis、SpringBoot整合redis、redisTemplate序列化及stringRedisTemplate序列化)
|
2月前
|
分布式计算 Java Hadoop
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
67 1
|
2月前
|
JSON Java 开发工具
Java服务端集成Google FCM推送的注意事项和实际经验
公司的app要上海外,涉及到推送功能,经过综合考虑,选择Google FCM进行消息推送。 查看一些集成博客和官方文档,看的似懂非懂,迷迷惑惑。本篇文章除了将我实际集成的经验分享出来,也会对看到的博客及其中产生的疑惑、注意事项一一评论。 从官方文档和众多博客中,你会发现Java集成FCM推送有多种实现方式,会让生产生文档很乱,不知作何选择的困惑。
100 0
|
4月前
|
Java
Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
Java使用FileInputStream&&FileOutputStream模拟客户端向服务器端上传文件(单线程)
90 1
|
5月前
|
消息中间件 Java Kafka
Java 客户端访问kafka
Java 客户端访问kafka
44 9
|
4月前
|
Java
Java模拟文件发送给服务器,服务器将文件转发给其他用户,并保存到服务器本地,其他用户可以接收,并保存到本地磁盘,支持各种文件格式,并解决通信中服务器怎么区分客户端发来的文件类型
Java模拟文件发送给服务器,服务器将文件转发给其他用户,并保存到服务器本地,其他用户可以接收,并保存到本地磁盘,支持各种文件格式,并解决通信中服务器怎么区分客户端发来的文件类型
|
5月前
|
Java 数据格式
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
99 0
|
5月前
|
JSON NoSQL Java
Redis18的Java客户端-StringRedisTemplate,序列化存在的问题,使用StringRedisTemplate解决序列化的方法
Redis18的Java客户端-StringRedisTemplate,序列化存在的问题,使用StringRedisTemplate解决序列化的方法