计算机网络实验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天前
|
监控 Unix Linux
采用异步socket实现客户端和服务端的通信
采用异步socket实现客户端和服务端的通信
5 0
|
7天前
|
XML JSON 网络协议
Socket实现模拟TCP通信粘包问题
Socket实现模拟TCP通信粘包问题
|
7天前
|
Java 开发者 Spring
Java一分钟之-Java网络编程基础:Socket通信
【5月更文挑战第13天】本文介绍了Java Socket编程基础知识,包括使用`ServerSocket`和`Socket`类建立连接,通过`OutputStream`和`InputStream`进行数据传输。常见问题涉及忘记关闭Socket导致的资源泄漏、网络异常处理及并发同步。理解Socket通信原理并掌握异常处理、资源管理和并发控制,能帮助开发者构建更稳定的网络应用。
32 1
|
7天前
|
存储 缓存 网络协议
【计网·湖科大·思科】实验二 计算机网络的寻址问题
【计网·湖科大·思科】实验二 计算机网络的寻址问题
5 0
|
7天前
|
网络协议 Java 网络安全
【计算机网络】—— Socket通信编程与传输协议分析
【计算机网络】—— Socket通信编程与传输协议分析
17 0
|
7天前
|
开发框架 网络协议 Java
【计算机网络】—— 网络应用通信基本原理
【计算机网络】—— 网络应用通信基本原理
13 0
|
2天前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
5天前
|
运维 网络协议 Linux
Docker网络_docker 网络,来看看这份超全面的《Linux运维面试题及解析》
Docker网络_docker 网络,来看看这份超全面的《Linux运维面试题及解析》
|
7天前
|
网络协议 Linux 网络架构