计算机网络实验socket通信

简介: 计算机网络实验socket通信

先上运行截图

1,运行服务端:

2,运行客户端,与服务端建立连接:

3,连接成功,发送消息:

4,客户端向服务端定期发送心跳包保持连通性:

接下来上代码:

1,服务端

package socket.ab;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server {
  //创建集合对象
  public static List<MyChannel> list=new ArrayList<MyChannel>();
  public static void main(String[] args) {
    try {
      System.out.println("服务器开始运行");
      ServerSocket serverSocket=new ServerSocket(8080);
      while(true) {
        Socket socket=serverSocket.accept();//接收客户请求
        
        //一个客户机与服务器通信
        //new Thread(new Listen(socket)).start();
        //new Thread(new Send(socket)).start();
        
        //服务器用于交换消息,创建线程类对象
        MyChannel channel=new MyChannel(socket);
        //添加到集合
        list.add(channel);
        if(list != null) {
          System.out.println("服务器收到"+channel+"连接");
        }
        
        new Thread(channel).start();
        
      }
    } catch (IOException e) {
      // TODO 自动生成的 catch 块
      e.printStackTrace();
    }
  }
}

2,集合对象

package socket.ab;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.List;
public class MyChannel implements Runnable{
  private Socket socket;
  private boolean flag=true;
  private ObjectInputStream ois;
  private ObjectOutputStream oos;
  //初始化
  public MyChannel(Socket socket){
    this.socket=socket;
    try {
      ois=new ObjectInputStream(socket.getInputStream());//获取输入流
      oos=new ObjectOutputStream(socket.getOutputStream());//获取输出流
    } catch (IOException e) {
      // TODO 自动生成的 catch 块
      e.printStackTrace();
      flag=false;
      try {
        socket.close();
      } catch (IOException e1) {
        // TODO 自动生成的 catch 块
        e1.printStackTrace();
      }
    }
  }
  //接收数据方法
  private String receive(){
    String str="";
    try {
      str=ois.readUTF();
      if(str.equals("我是心跳包")) {
        System.out.println(str);
      }
    } catch (IOException e) {
      System.out.println("断开连接");
      flag=false;
      try {
        socket.close();
      } catch (IOException e1) {
        Server.list.remove(this);
      }
    }
    return str;
  }
  //发送数据方法
  private void send(String str) {
    if(str!=null&&str.length()!=0) {
      if(!str.equals("我是心跳包")) {
        try {
          oos.writeUTF(str);
          oos.flush();
        } catch (IOException e) {
          flag=false;
          try {
            socket.close();
//            Server.list.remove(this);
          } catch (IOException e1) {
//            Server.list.remove(this);
          }
        }
      }
    }
  }
  //转发
  private void sendOther() {
    String str=this.receive();
    List<MyChannel> list=Server.list;
    if(list.size()>1) {
      for(MyChannel other :list) {
        if(other==this) {
          continue;//不发给自己
        }
        other.send(str);
      }
    }
  }
  @Override
  public void run() {
    // TODO 自动生成的方法存根
    while(flag) {
      //this.send(receive());
      sendOther();
    }
  }
}

3,send方法

package socket.ab;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Send implements Runnable{
  private Socket socket;
  private ObjectOutputStream oos;
  public static String name="";
  Send(Socket socket,String name,ObjectOutputStream oos){
    this.socket=socket;
    Send.name=name;
    this.oos=oos;
  }
  String str="";
  @Override
  public void run() {
    // TODO 自动生成的方法存根
    try {
      while(true) {
          Thread.sleep(1000);
          oos.writeUTF(Frame.text);
          oos.flush();
          Frame.text="";
      }
    } catch (IOException | InterruptedException e) {
      System.out.println("发送失败");
    }
  }
  
}

4,listen方法

package socket.ab;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;
public class Listen implements Runnable{
  private Socket socket;
  //初始化
  Listen(Socket socket){
    this.socket=socket;
  }
  @Override
  public void run() {
    // TODO 自动生成的方法存根
    try {
      //获取输入流
      ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
      while(true) {
        String read=ois.readUTF();
        Frame.jtx.append(Frame.date()+"\n"+"收到"+read+"\n");
//        System.out.println("收到"+ois.readUTF());
      }
    } catch (IOException e) {
      System.out.println("接收失败");
      Client.connet_state=false;
      Client.reconnet();
    }finally {
      try {
        socket.close();
      } catch (IOException e) {
        // TODO 自动生成的 catch 块
        e.printStackTrace();
      }
    }
  }
}

5,客户端

package socket.ab;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
  private static Socket socket;
  private static ObjectOutputStream oos;
  public static boolean connet_state=false;
  public static String name=Frame.tit;
//  static String[] arrays=new String[5];
  
  public static void main(String[] args) {
    new Frame();
    System.out.println(name+"连接到服务器");
    connet();
    if(connet_state) {
      try {
        oos=new ObjectOutputStream(socket.getOutputStream());
        new Thread(new Listen(getSocket())).start();
        new Thread(new Send(getSocket(),name,oos)).start();
        new Thread(new HeartBeat(getSocket(),oos)).start();
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
  private static void connet() {
    try {
      setSocket(new Socket("127.0.0.1",8080));
      connet_state=true;
    } catch (UnknownHostException e) {
      // TODO 自动生成的 catch 块
      e.printStackTrace();
      connet_state=false;
    } catch (IOException e) {
      // TODO 自动生成的 catch 块
      e.printStackTrace();
      connet_state=false;
    }
  }
  public static void reconnet() {
    while(!connet_state) {
      System.out.println("尝试重新连接...");  
      try {
        connet();
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
    if(connet_state) {
      try {
        oos=new ObjectOutputStream(socket.getOutputStream());
        new Thread(new Listen(getSocket())).start();
        new Thread(new Send(getSocket(),name,oos)).start();
        new Thread(new HeartBeat(getSocket(),oos)).start();
        System.out.println("重连成功");
      } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }
  }
  public static Socket getSocket() {
    return socket;
  }
  public static void setSocket(Socket socket) {
    Client.socket = socket;
  }
}

6,界面显示

package socket.ab;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
public class Frame extends java.awt.Frame implements Runnable{
  public static JTextArea jtx=new JTextArea(200,150);
  public static TextField tf=new TextField(30);
  public Frame() {
    initFrame();
    initEventListner();
  }
  public static String text="";
  public static String tit="用户"+new Random().nextInt(900)+100;
  public static String tit2=tit;
//  public static String getTit() {
//    return tit;
//  }
  public static boolean sendflag=true;
//  public static String getText() {
//    return text;
//  }
  private void initFrame() {
    setTitle(tit);
    setSize(600, 500);
    setLocation(new Random().nextInt(500)+100, new Random().nextInt(900)+100);
    setResizable(false);
    Panel p=new Panel();
    
    setLayout(new BorderLayout());
    //滚动条
    JScrollPane j=new JScrollPane();
    j.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    j.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
//    JTextArea jtx=new JTextArea(200,150);
    jtx.setFocusable(false);
    j.setViewportView(jtx);
    add(j,BorderLayout.CENTER);
    p.setLayout(new FlowLayout());
    add(p,BorderLayout.SOUTH);
    
    Button btn=new Button("发送");
    
    tf.requestFocus();
    p.add(tf);
    p.add(btn);
    btn.addActionListener(new ActionListener() {
      
      @Override
      public void actionPerformed(ActionEvent e) {
        // TODO 自动生成的方法存根
//        if(text!=null && !text.trim().equals("")) {
          text=Send.name+":"+tf.getText();
          jtx.append(date()+"\n");
          jtx.append("我发送了:"+tf.getText()+"\n");
          sendflag=true;
          tf.setText("");
//        }
      }
    });
    
    setVisible(true);
    repaint();
    
  }
  public static String date() {
    Date time=new Date();
    SimpleDateFormat format=new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
    return "----------"+format.format(time);
    
  }
  private void initEventListner() {        
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
                System.exit(0);
           }
        });
    }
  @Override
  public void run() {
    // TODO 自动生成的方法存根
    new Frame();
  }
}

7,心跳包测试

package socket.ab;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class HeartBeat implements Runnable{
  private Socket socket;
  private ObjectOutputStream oos;
  public static String heart="我是心跳包";
  public HeartBeat(Socket socket,ObjectOutputStream oos){
    this.socket=socket;
    this.oos=oos;
  }
  
  @Override
  public void run() {
    // TODO Auto-generated method stub
    System.out.println("心跳包线程已启动...");
    try {
      while(true) {
        Thread.sleep(5000);
        oos.writeUTF(heart);
//        oos.flush();
      }
      
    } catch (InterruptedException | IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      Client.connet_state=false;
      Client.reconnet();
    }
  }
}

点赞支持一下吧~

相关文章
|
1月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
65 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
2月前
|
安全 搜索推荐 网络安全
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
86 11
|
2月前
|
网络协议
计算机网络与通信
计算机网络基本概念:了解计算机网络的定义、功能、分类和拓扑结构(如总线型、星型、环型、树形、网状等)。 网络通信原理:了解网络通信的基本原理、协议和技术,如TCP/IP协议、网络通信设备等。
37 3
|
2月前
|
算法
数据结构之卫星通信网络(BFS)
本文介绍了卫星通信网络及其重要性,并探讨了广度优先搜索(BFS)算法在其中的应用。卫星通信网络通过在轨卫星提供全球覆盖的通信服务,尤其在偏远地区和紧急救援中发挥关键作用。BFS算法用于网络拓扑分析、路径规划和故障排除,确保通信网络的高效运行。文章还包括BFS算法的工作原理、特点、优缺点及其实现代码示例。
64 1
|
2月前
|
传感器 自动驾驶 物联网
探秘 5G 核心网络之 5G RAN:开启高速通信新时代
探秘 5G 核心网络之 5G RAN:开启高速通信新时代
87 4
|
2月前
|
物联网 5G 数据中心
|
2月前
|
网络协议 算法 数据库
OSPF 与 BGP 的互操作性:构建复杂网络的通信桥梁
OSPF 与 BGP 的互操作性:构建复杂网络的通信桥梁
60 0
|
2月前
|
边缘计算 5G 数据处理
5G网络能耗管理:绿色通信的实践
【10月更文挑战第30天】
58 0
|
2月前
|
存储 缓存 网络协议
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点,GET、POST的区别,Cookie与Session
计算机网络常见面试题(二):浏览器中输入URL返回页面过程、HTTP协议特点、状态码、报文格式,GET、POST的区别,DNS的解析过程、数字证书、Cookie与Session,对称加密和非对称加密
|
2月前
|
网络协议 算法 网络性能优化
计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
计算机网络常见面试题(一):TCP/IP五层模型、应用层常见的协议、TCP与UDP的区别,TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议、ARP协议