网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)(下)

简介: 网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)

网络编程【TCP单向通信、TCP双向通信、一对多应用、一对多聊天服务器】(二)-全面详解(学习总结---从入门到深化)(上):https://developer.aliyun.com/article/1419279


创建客户端

/**
* 用于发送消息的线程类
*/
class ClientSend extends Thread{
    private Socket socket;
    public ClientSend(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.sendMsg();
   }
    /**
     * 发送消息
     */
    private void sendMsg(){
        //创建Scanner对象
        try(Scanner scanner = new Scanner(System.in);
            //创建向对方输出消息的流对象
            PrintWriter pw = new PrintWriter(this.socket.getOutputStream());)
            {
            while(true){
                String msg = scanner.nextLine();
                pw.println(msg);
                pw.flush();
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
/**
* 用于接收消息的线程类
*/
class ClientReceive extends Thread{
    private Socket socket;
    public ClientReceive(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.receiveMsg();
   }
    /**
     * 用于接收对方消息的方法
     */
    private void receiveMsg(){
        //创建用于接收对方发送消息的流对象
        try(BufferedReader br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));){
            while(true){
                String msg = br.readLine();
                System.out.println("他说:"+msg);
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
public class ChatSocketClient {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1", 8888);
            System.out.println("连接成功!");
            new ClientSend(socket).start();
            new ClientReceive(socket).start();
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}


优化点对点聊天应用

/**
* 发送消息线程
*/
class Send extends Thread{
    private Socket socket;
    private Scanner scanner;
    public Send(Socket socket,Scanner scanner){
        this.socket = socket;
        this.scanner = scanner;
}
    @Override
    public void run() {
        this.sendMsg();
   }
    /**
     * 发送消息
     */
    private void sendMsg(){
        //创建向对方输出消息的流对象
        try(PrintWriter pw = new PrintWriter(this.socket.getOutputStream()))
{
            while(true){
                String msg = scanner.nextLine();
                pw.println(msg);
                pw.flush();
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
/**
* 接收消息的线程
*/
class Receive extends Thread{
    private Socket socket;
  public Receive(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.receiveMsg();
   }
    /**
     * 用于接收对方消息的方法
     */
    private void receiveMsg(){
        //创建用于接收对方发送消息的流对象
        try(BufferedReader br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()))){
            while(true){
                String msg = br.readLine();
                System.out.println("他说:"+msg);
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
public class GoodTCP {
    public static void main(String[] args)
      {
        Scanner scanner = null;
        ServerSocket serverSocket = null;
        Socket socket = null;
        try{
            scanner = new Scanner(System.in);
            System.out.println("请输入:server,<port> 或者:<ip>,<port>");
            String str = scanner.nextLine();
            String[] arr = str.split(",");
            if("server".equals(arr[0])){
                //启动服务端
                System.out.println("TCP Server Listen at "+arr[1]+" .....");
                serverSocket = new ServerSocket(Integer.parseInt(arr[1]));
                socket = serverSocket.accept();
                System.out.println("连接成功!");
           }else{
                //启动客户端
                socket = new Socket(arr[0],Integer.parseInt(arr[1]));
                System.out.println("连接成功!");
           }
            //启动发送消息的线程
            new Send(socket,scanner).start();
            //启动接收消息的线程
         }catch(Exception e){
            e.printStackTrace();
       }finally{
            if(serverSocket != null){
                try {
                    serverSocket.close();
               } catch (IOException e) {
                    e.printStackTrace();
               }
           }
       }
   }
}


一对多应用


一对多应用设计


各socket对间独立问答,互相间不需要传递信息。


一对多应答型服务器

/**
* 定义消息处理线程类
*/
class Msg extends Thread{
    private Socket socket;
    public Msg(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.msg();
   }
    /**
     * 将从客户端读取到的消息写回给客户端
     */
    private void msg(){
        try(BufferedReader br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
            PrintWriter pw = new PrintWriter(this.socket.getOutputStream())){
            while(true){
                pw.println(br.readLine()+" [ok]");
                pw.flush();
           }
       }catch(Exception e){
            e.printStackTrace();
          System.out.println(this.socket.getInetAddress()+" 断线了!");
       }
   }
}
public class EchoServer {
    public static void main(String[] args) {
        try(ServerSocket serverSocket = new ServerSocket(8888)){
            //等待多客户端连接
            while(true){
                Socket socket = serverSocket.accept();
                new Msg(socket).start();
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}


一对多聊天服务器


服务器设计


1、服务器的连接设计


2、服务器的线程设计


创建一对多聊天服务应用

/**
* 接收客户端消息的线程类
*/
class ChatReceive extends Thread{
    private Socket socket;
    public ChatReceive(Socket socket){
        this.socket =socket;
   }
    @Override
    public void run() {
        this.receiveMsg();
   }
    /**
     * 实现接收客户端发送的消息
     */
    private void receiveMsg(){
        try(BufferedReader br = new BufferedReader(new InputStreamReader(this.socket.getInputStream()))){
            while(true){
                String msg = br.readLine();
                synchronized ("abc"){
                    //把读取到的数据写入公共数据区
                    ChatRoomServer.buf=" ["+this.socket.getInetAddress()+"] "+msg;
                    //唤醒发送消息的线程对象。
                    "abc".notifyAll();
               }
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
/**
* 向客户端发送消息的线程类
*/
class ChatSend extends Thread{
    private Socket socket;
    public ChatSend(Socket socket){
        this.socket = socket;
   }
    @Override
    public void run() {
        this.sendMsg();
   }
    /**
     * 将公共数据区的消息发送给客户端
     */
    private void sendMsg(){
        try(PrintWriter  pw = new PrintWriter(this.socket.getOutputStream())){
            while(true){
                synchronized ("abc"){
                    //让发送消息的线程处于等待状态
                    "abc".wait();
                    //将公共数据区中的消息发送给客户端
                    pw.println(ChatRoomServer.buf);
                    pw.flush();
               }
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}
public class ChatRoomServer {
    //定义公共数据区
    public static String buf;
    public static void main(String[] args) {
        System.out.println("Chat Server Version 1.0");
        System.out.println("Listen at 8888.....");
        try(ServerSocket serverSocket = new ServerSocket(8888)){
            while(true){
                Socket socket = serverSocket.accept();
                System.out.println("连接到:"+socket.getInetAddress());
                new ChatReceive(socket).start();
                new ChatSend(socket).start();
           }
       }catch(Exception e){
            e.printStackTrace();
       }
   }
}



目录
相关文章
|
4天前
|
存储 网络协议 关系型数据库
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
Python从入门到精通:2.3.2数据库操作与网络编程——学习socket编程,实现简单的TCP/UDP通信
|
4天前
|
移动开发 Java Android开发
构建高效Android应用:采用Kotlin协程优化网络请求
【4月更文挑战第24天】 在移动开发领域,尤其是对于Android平台而言,网络请求是一个不可或缺的功能。然而,随着用户对应用响应速度和稳定性要求的不断提高,传统的异步处理方式如回调地狱和RxJava已逐渐显示出局限性。本文将探讨如何利用Kotlin协程来简化异步代码,提升网络请求的效率和可读性。我们将深入分析协程的原理,并通过一个实际案例展示如何在Android应用中集成和优化网络请求。
|
10天前
|
存储 监控 安全
网络安全与信息安全:防范漏洞、应用加密、提升意识
【4月更文挑战第18天】 在数字化时代,网络安全与信息安全保障已成为维护国家安全、企业利益和个人隐私的关键。本文深入探讨网络安全的多面性,包括识别和防御网络漏洞、应用加密技术保护数据以及提升全民网络安全意识的重要性。通过对这些关键领域的分析,文章旨在为读者提供实用的策略和建议,以增强其网络环境的安全防护能力。
10 0
|
11天前
|
数据采集 机器学习/深度学习 数据挖掘
网络数据处理中的NumPy应用实战
【4月更文挑战第17天】本文介绍了NumPy在网络数据处理中的应用,包括数据预处理、流量分析和模式识别。通过使用NumPy进行数据清洗、格式化和聚合,以及处理时间序列数据和计算统计指标,可以有效进行流量分析和异常检测。此外,NumPy还支持相关性分析、周期性检测和聚类分析,助力模式识别。作为强大的科学计算库,NumPy在处理日益增长的网络数据中发挥着不可或缺的作用。
|
19天前
|
传感器 监控 安全
|
19天前
|
安全 SDN 数据中心
|
1月前
|
网络协议 算法 Java
|
3月前
|
Java 数据格式
最新Java基础系列课程--Day15-网络编程(三)
最新Java基础系列课程--Day15-网络编程
|
3月前
|
存储 网络协议 Java
最新Java基础系列课程--Day15-网络编程(二)
最新Java基础系列课程--Day15-网络编程
|
9天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。