计算机网络实验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();
    }
  }
}

点赞支持一下吧~

相关文章
|
4月前
|
网络协议 Unix Linux
# 2个类轻松构建高效Socket通信库
本文介绍了一种通过两个类`EpollEventHandler`和`IEpollEvent`构建高效Socket通信库的方法。该库支持TCP、UDP和Unix域套接字,采用I/O多路复用技术(如epoll),提升并发处理能力。通过抽象基类和具体事件类的设计,简化了API使用,便于开发者快速上手。文章还提供了服务端与客户端的实例代码,展示其在实际项目中的应用效果。此Socket库适应嵌入式环境,功能定制性强,有助于减少外部依赖并提升维护效率。
117 65
# 2个类轻松构建高效Socket通信库
|
4月前
|
网络协议 开发者 Python
Socket如何实现客户端和服务器间的通信
通过上述示例,展示了如何使用Python的Socket模块实现基本的客户端和服务器间的通信。Socket提供了一种简单且强大的方式来建立和管理网络连接,适用于各种网络编程应用。理解和掌握Socket编程,可以帮助开发者构建高效、稳定的网络应用程序。
151 10
|
5月前
|
canal 编解码 运维
飞天洛神云网络再度入选通信顶会 SIGCOMM'24
飞天洛神云网络再度入选通信顶会 SIGCOMM'24
140 12
|
5月前
|
人工智能 自然语言处理 决策智能
智能体竟能自行组建通信网络,还能自创协议提升通信效率
《一种适用于大型语言模型网络的可扩展通信协议》提出创新协议Agora,解决多智能体系统中的“通信三难困境”,即异构性、通用性和成本问题。Agora通过标准协议、结构化数据和自然语言三种通信格式,实现高效协作,支持复杂任务自动化。演示场景显示其在预订服务和天气预报等应用中的优越性能。论文地址:https://arxiv.org/pdf/2410.11905。
126 6
|
5月前
|
缓存 网络协议 安全
即时通讯初学者必知必会的20个网络编程和通信安全知识点
即时通讯IM应用开发的初学者很容易迷失在网络编程的复杂性以及通信安全的各种概念里,本文不涉及深度理论知识,尽量通过一句话或几句话让你快速了解20个相关的网络编程和通信安全知识点,希望能助你愉快地开始即时通讯应用开发。
95 0
|
7月前
|
负载均衡 网络协议 算法
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
这网络层就像搭积木一样,上层协议都是基于下层协议搭出来的。不管是ping(用了ICMP协议)还是tcp本质上都是基于网络层IP协议的数据包,而到了物理层,都是二进制01串,都走网卡发出去了。 如果网络环境没发生变化,目的地又一样,那按道理说他们走的网络路径应该是一样的,什么情况下会不同呢? 我们就从路由这个话题聊起吧。
172 4
不为人知的网络编程(十九):能Ping通,TCP就一定能连接和通信吗?
|
8月前
|
安全 搜索推荐 网络安全
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
HTTPS协议是**一种通过计算机网络进行安全通信的传输协议
175 11
|
8月前
|
网络协议
计算机网络与通信
计算机网络基本概念:了解计算机网络的定义、功能、分类和拓扑结构(如总线型、星型、环型、树形、网状等)。 网络通信原理:了解网络通信的基本原理、协议和技术,如TCP/IP协议、网络通信设备等。
143 3
|
8月前
|
网络协议 算法 数据库
OSPF 与 BGP 的互操作性:构建复杂网络的通信桥梁
OSPF 与 BGP 的互操作性:构建复杂网络的通信桥梁
195 0
|
9月前
|
网络协议 测试技术 网络安全
Python编程-Socket网络编程
Python编程-Socket网络编程
87 0