Java网络编程-服务端程序实现

本文涉及的产品
系统运维管理,不限时长
简介: Java网络编程-服务端程序实现

 最近学习了Java的net包,看了网上的开源代码,整理了一部分服务端代码,实现了消息监听,直接上代码。

一。新建了一个消息类,用于存储消息进行传输

package com.xing.studyTest.net.im.model;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
/**
 *  消息信息
 * @author xinghua
 *
 */
public class MessageBean implements Serializable{
  private static final long serialVersionUID = 1L;
  private int type; // 1私聊 0上下线更新 -1下线请求 2请求发送文件 3.确定接收文件
  private HashSet<String> clients; // 存放选中的客户
  private HashSet<String> to;//
  public HashMap<String, MessageBean> onlines;//
  private String info;//信息
  private String timer;//时间
  private String name;//昵称
  private String fileName;//文件名
  private int size;//文件大小
  private String ip;//IP
  private int port;//端口
  public int getSize() {
    return size;
  }
  public void setSize(int size) {
    this.size = size;
  }
  public String getFileName() {
    return fileName;
  }
  public void setFileName(String fileName) {
    this.fileName = fileName;
  }
  public HashSet<String> getTo() {
    return to;
  }
  public void setTo(HashSet<String> to) {
    this.to = to;
  }
  public int getType() {
    return type;
  }
  public void setType(int type) {
    this.type = type;
  }
  public HashSet<String> getClients() {
    return clients;
  }
  public void setClients(HashSet<String> clients) {
    this.clients = clients;
  }
  public String getInfo() {
    return info;
  }
  public void setInfo(String info) {
    this.info = info;
  }
  public String getTimer() {
    return timer;
  }
  public void setTimer(String timer) {
    this.timer = timer;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getIp() {
    return ip;
  }
  public void setIp(String ip) {
    this.ip = ip;
  }
  public int getPort() {
    return port;
  }
  public void setPort(int port) {
    this.port = port;
  }
  public HashMap<String, MessageBean> getOnlines() {
    return onlines;
  }
  public void setOnlines(HashMap<String, MessageBean> onlines) {
    this.onlines = onlines;
  }
  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return " [type=" + type + ", clients=" + clients + ", to=" + to + ", onlines=" + onlines + ", info="
        + info + ", timer=" + timer + ", name=" + name + ", fileName=" + fileName + ", size=" + size + ", ip="
        + ip + ", port=" + port + "]";
  }
}

image.gif

二、因为要存储在线用户和用户连接信息,所以还需要个实体类

package com.xing.studyTest.net.im.model;
import java.io.Serializable;
import java.net.Socket;
/**
 *  连接信息
 * @author xinghua
 *
 */
public class SocketBean implements Serializable{
  private static final long serialVersionUID = 1L;
  private String name;//名称
  private Socket socket;//socket
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Socket getSocket() {
    return socket;
  }
  public void setSocket(Socket socket) {
    this.socket = socket;
  }
  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString() {
    return "ServerBean [name=" + name + ", socket=" + socket + "]";
  }
}

image.gif

三,好了,接下来就是Server代码

package com.xing.studyTest.net.im.server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import com.xing.studyTest.net.im.model.MessageBean;
import com.xing.studyTest.net.im.model.SocketBean;
/**
 *  
 * @author xinghua
 *
 */
public class SocketServer {
  private static ServerSocket ss;//服务端服务对象
  public static HashMap<String, SocketBean> onlines;//存储上线的Socket信息
  //1.准备服务端对象及容器
  static {
    try {
      ss = new ServerSocket(8520);
      onlines = new HashMap<String, SocketBean>();//新建一个容器存放客户端连接信息
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
  //2.多线程实现监听消息处理
  class CatClientThread extends Thread {
    private Socket socket;//链接
    private MessageBean messageBean;//消息
    private ObjectInputStream ois;//读取消息
    private ObjectOutputStream oos;//输出消息
    public CatClientThread(Socket socket) {
      this.socket = socket;
    }
    @Override
    public void run() {
      try {
        messageBean = (MessageBean)new ObjectInputStream(socket.getInputStream()).readObject();
        System.out.println("获取消息对象:"+messageBean);
        //根据请求类型进行不同的操作
        switch (messageBean.getType()) {
          case 0: {  // 上线 
            System.out.println("上线1.记录上线客户的用户名和端口,组装用户名和Socket连接,添加到容器中");
            SocketBean socketBean = new SocketBean();
            socketBean.setName(messageBean.getName());
            socketBean.setSocket(socket);
            onlines.put(messageBean.getName(), socketBean);//添加到onlines中
            System.out.println("上线2.已存储上线,开始准备发送消息给客户端");
            System.out.println("当前在线人数:【"+onlines.keySet().size()+"】个");
            MessageBean returnMessageBean = new MessageBean();
            returnMessageBean.setType(0);
            returnMessageBean.setInfo(messageBean.getTimer() + "  [ " + messageBean.getName() + " ]上线了");
            System.out.println("上线3.发送消息准备完毕,发送给全部用户:");
            System.out.println(onlines.keySet());
//            System.out.println(onlines.values());
            HashSet<String> set = new HashSet<String>();
            set.addAll(onlines.keySet());
            returnMessageBean.setClients(set);
            sendAll(returnMessageBean);
            System.out.println("上线4.发送有人上线消息给全部用户完毕");
            break;
          }
          case -1: { // 下线
//            try {
//              oos = new ObjectOutputStream(socket.getOutputStream());
//              oos.writeObject(messageBean);
//              oos.flush();
//            } catch (IOException e) {
//              e.printStackTrace();
//            }
            System.out.println("下线1.将用户从容器删除");
            onlines.remove(messageBean.getName());
            System.out.println("下线2.用户已移除,准备发送消息告诉所有人他下线了");
            MessageBean returnMessageBean = new MessageBean();
            returnMessageBean.setType(-1);
            returnMessageBean.setInfo(messageBean.getTimer() + "  [ " + messageBean.getName() + " ]下线了");
            System.out.println("下线3.发送消息准备完毕,发送给全部用户");
            sendAll(returnMessageBean);
            System.out.println("下线4.发送有人下线消息给全部用户完毕");
            break;
          }
          case 1: {  // 聊天
            System.out.println("聊天1.组装消息,准备给选中的用户发送");
            MessageBean returnMessageBean = new MessageBean();
            returnMessageBean.setType(1);
            returnMessageBean.setClients(messageBean.getClients());
            returnMessageBean.setName(messageBean.getName());//选中的用户昵称
            returnMessageBean.setInfo(messageBean.getInfo());//消息内容
            returnMessageBean.setTimer(messageBean.getTimer());//发送时间
            System.out.println("聊天2.组装消息准备完毕开始发送");
            System.out.println(returnMessageBean);
            sendMessage(returnMessageBean);
            System.out.println("聊天3.发送消息完毕");
            break;
          }
          case 2: {  // 请求接受文件
            break;
          }
          case 3: {  // 确定接收文件
            break;
          }
          default: {
            break;
          }
        }
      } catch (Exception e) {
        e.printStackTrace();
      } finally {
        close();
      }
    }
    // 向选中的用户发送数据
    private void sendMessage(MessageBean messageBean) {
      // 首先取得所有的values
      Set<String> cbs = onlines.keySet();
      Iterator<String> it = cbs.iterator();
      // 选中客户
      HashSet<String> clients = messageBean.getClients();
      while (it.hasNext()) {
        // 在线客户
        String client = it.next();
        // 选中的客户中若是在线的,就发送
        if (clients.contains(client)) {
          Socket c = onlines.get(client).getSocket();
          ObjectOutputStream oos;
          try {
            oos = new ObjectOutputStream(c.getOutputStream());
            oos.writeObject(messageBean);
            oos.flush();
          } catch (IOException e) {
            e.printStackTrace();
          }
        }
      }
    }
    /*
     *  向所有的用户发送数据
     */
    public void sendAll(MessageBean serverBean) {
      Collection<SocketBean> clients = onlines.values();
      Iterator<SocketBean> it = clients.iterator();
      ObjectOutputStream oos;
      while (it.hasNext()) {
        Socket c = it.next().getSocket();
        try {
          oos = new ObjectOutputStream(c.getOutputStream());
          oos.writeObject(serverBean);
          oos.flush();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    /*
     * 关闭Socket连接
     */
    private void close() {
      if (oos != null) {
        try {
          oos.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (ois != null) {
        try {
          ois.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      if (socket != null) {
        try {
          socket.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
  }
  /*
   *  循环调用监听与本Socket的连接信息,
   */
  public void start() {
    try {
      Executor executor = Executors.newFixedThreadPool(3);
      while (true) {
        String name = ss.getInetAddress().getHostName();
        System.out.println("启动服务器监听程序启动完成,快来给我发送消息把!:host:"+name+"port:"+ss.getLocalPort());
        Socket socket = ss.accept();
        name = socket.getInetAddress().getHostName();
        System.out.println("收到host:"+name+"port:"+socket.getPort()+"的消息处理开始");
        Long timeStart = System.currentTimeMillis();
        executor.execute(new CatClientThread(socket));
//        new CatClientThread(socket).start();
        System.out.println("收到host:"+name+"port:"+socket.getPort()+"的消息处理完毕,用时【"+(System.currentTimeMillis()-timeStart)+"】秒");
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  } 
}

image.gif

四、最后启动:

package com.xing.studyTest.net.im.main;
import com.xing.studyTest.net.im.server.SocketServer;
/**
 *  启动服务端
 * @author xinghua
 *
 */
public class ServerApplication {
  public static void main(String[] args) {
    new SocketServer().start();
  }
}

image.gif

五、此时就在监听 等待客户端发消息来连接了

image.gif编辑

六、简单的客户端搞个上线信息发送:

package com.xing.studyTest.net.im.main;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import com.xing.studyTest.net.im.model.MessageBean;
/**
 *  客户端
 * @author xinghua
 *
 */
public class ClientApplication2 {
  private static final String HOST = "localhost";//host
  private static final int PORT = 8520;//端口
  private static final String NAME = "雅楠";//host
  public static void main(String[] args) {
    Socket socket = null;
    DataInputStream dataInputStream = null;
    DataOutputStream dataOutputStream = null;
    try {
      Scanner input = new Scanner(System.in);
      System.out.println("请输入一个昵称");
      String name = input.nextLine();
      System.out.println("你的昵称是【"+name+"】,开始连接。。。");
      //上线
      MessageBean messageBean = new MessageBean();
      messageBean.setType(0);
      messageBean.setName(name);
      messageBean.setTimer(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
      socket = new Socket(HOST, PORT);
//      System.out.println("发起请求到->"+HOST+":"+PORT);
      ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
      oos.writeObject(messageBean);
      oos.flush();
      System.out.println("获取响应数据");
      MessageBean resMB = (MessageBean)new ObjectInputStream(socket.getInputStream()).readObject();
      System.out.println(resMB);
      System.out.println();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if(dataInputStream != null){
          dataInputStream.close();
        }
        if(dataOutputStream != null){
        dataOutputStream.close();
        }
        if(socket != null){
          socket.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
      }
    } 
  }
}

image.gif

这是搞了个上线消息发送,并收到响应,客户端应该是不停的监听服务端发送消息,以实现聊天,还没写出来,下次再贴出来吧

image.gif编辑

好吧,自己发给自己了,啊哈哈哈哈

image.gif编辑

目录
相关文章
|
9天前
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
33 9
|
9天前
|
人工智能 Java 物联网
JAVA网络编程的未来:URL与URLConnection的无限可能,你准备好了吗?
随着技术的发展和互联网的普及,JAVA网络编程迎来新的机遇。本文通过案例分析,探讨URL与URLConnection在智能API调用和实时数据流处理中的关键作用,展望其未来趋势和潜力。
33 7
|
9天前
|
Java 开发者
JAVA高手必备:URL与URLConnection,解锁网络资源的终极秘籍!
在Java网络编程中,URL和URLConnection是两大关键技术,能够帮助开发者轻松处理网络资源。本文通过两个案例,深入解析了如何使用URL和URLConnection从网站抓取数据和发送POST请求上传数据,助力你成为真正的JAVA高手。
27 11
|
9天前
|
安全 Java API
深入探索Java网络编程中的HttpURLConnection:从基础到进阶
本文介绍了Java网络编程中HttpURLConnection的高级特性,包括灵活使用不同HTTP方法、处理重定向、管理Cookie、优化安全性以及处理大文件上传和下载。通过解答五个常见问题,帮助开发者提升网络编程的效率和安全性。
|
9天前
|
JSON 安全 算法
JAVA网络编程中的URL与URLConnection:那些你不知道的秘密!
在Java网络编程中,URL与URLConnection是连接网络资源的两大基石。本文通过问题解答形式,揭示了它们的深层秘密,包括特殊字符处理、请求头设置、响应体读取、支持的HTTP方法及性能优化技巧,帮助你掌握高效、安全的网络编程技能。
38 9
|
9天前
|
JSON Java API
JAVA网络编程新纪元:URL与URLConnection的神级运用,你真的会了吗?
本文深入探讨了Java网络编程中URL和URLConnection的高级应用,通过示例代码展示了如何解析URL、发送GET请求并读取响应内容。文章挑战了传统认知,帮助读者更好地理解和运用这两个基础组件,提升网络编程能力。
31 5
|
网络协议 Java API
|
缓存 网络协议 Java