Scoket 传输代码实现

发布时间 2023-11-16 17:20:59作者: 捞月亮的小北

前提 : 开发工具 : IDEA ,创建包 : com.north.test , 才能直接复制

服务端

package com.north.test;

import javax.swing.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;

public class server {
    private ServerSocket ss = null; //用以指明服务器的端口号和接受来自客户端的信息
    private Socket sc =null; //服务器的套接字
    private static int pocket = 8888; //端口号
    private InputStream ips = null; //输出流
    private  boolean start = false; //判断服务器是否启动
    private static JFrame jf = new JFrame(); //GUI界面
    private static JTextArea ja = new JTextArea(10, 20); //GUI界面
    private ArrayList<Thread_server> ccList = new ArrayList<Thread_server>(); //构造容器来存储客户端


    //主函数入口
    public static void main(String[] args) {
        server s = new server();
        s.init_gui(); //初始化GUI界面
        s.getmassage(); //服务器端得到信息后的操作
    }


    //初始化GUI界面
    public static void init_gui(){
        jf.setBounds(300, 300, 400, 400);
        jf.setTitle("服务器窗口");
        //设置为不可编辑
        ja.setEditable(false);
        //添加组件
        jf.add(ja);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.setVisible(true);
    }

    //服务器端得到信息后的操作
    public  void getmassage(){
        try{
            //指明服务器端的端口号并创建服务器端的socket
            ss = new ServerSocket(pocket);
            start = true;//服务器已经打开
            //因为要实现多人聊天,因此需要循环监听客户端
            while(start){
                sc = ss.accept(); //服务器的套接字和客户端的套接字连接
                System.out.println("一个客户端已加入连接:"+sc.getPort()); //打印消息
                ja.append("服务器信息:一个客户端连接服务器" + sc.getInetAddress() + "/" + sc.getPort()+'\n'); //GUI界面中打印消息
                //因为可能存在有多个客户端连接,因此需要创建多线程来实现
                Thread_server ts = new Thread_server(sc);
                ccList.add(ts); //用集合来储存客户端的socket
                ts.start(); //线程的启动
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(ss!=null){
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(sc!=null){
                try {
                    sc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ips!=null){
                try {
                    ips.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }



    //创建多线程的内部类
    class Thread_server extends Thread{
        Socket sc = null;

        public Thread_server(Socket sc){
            this.sc = sc;
        }

        @Override
        //服务器端接受并反馈来自客户端的信息
        public void run() {
            InputStream ips = null;
            try{
                ips = sc.getInputStream();
                byte[] b = new byte[1024];
                int len;
                String str = null;
                while((len=ips.read(b))!=-1){
                    str = new String(b);
                    System.out.println(str);
                    ja.append(str+'\n');

                    //服务器端给所有的客户端发送消息
                    Iterator<Thread_server> iterator = ccList.iterator();
                    while (iterator.hasNext() && ccList.size()>=2) {
                        Thread_server th = iterator.next();
                        if(th.sc != sc){
                            th.sendmassage(str); //发送消息的函数
                        }
                    }
                    //初始化byte[] 数组
                    for(int i = 0 ; i<1024 ; i++){
                        b[i]=0;
                    }
                }
            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try {
                    ips.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        //服务器端给每个客户端发送消息
        public void sendmassage(String str){
            OutputStream ops = null;
            try {
                ops = sc.getOutputStream();
                ops.write(str.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }

        }


    }
}

JavaBean

package com.north.test;

public class customer {
    private String name;
    String id;
    String mima;

    public customer(String name,String id,String mima){
        this.name = name;
        this.id = id;
        this.mima = mima;
    }

    public customer(String name){
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

客户端

package com.north.test;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;

public class client {
    private Socket sc = null; //客户端的套接字
    private  InputStream ips = null;
    private OutputStream ops = null;
    private static int pocket = 8888;
    private static String ip ="127.0.0.1"; //服务器端的ip地址,这里用的就是本机地址
    private  customer cust = null; //customer实体类
    private boolean first = true; //判断该客户端是否是第一次给服务器端发信息
    private JTextArea ja;
    private JFrame jf;
    private JTextField jt;

    //创建用户名
    public  void customer_init(){
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入姓名:");
        String name = sc.next();
        cust = new customer(name);

    }

    //给服务器端发送消息的方法
    public void send(String str){
        try{
            ops = sc.getOutputStream();
            if(first){
                ops.write(("                  \t        "+str+'\n').getBytes());
                first = false;
            }else {
                ops.write((this.cust.getName() + "说:" + str).getBytes());
                //ja.append("我说:"+str+'\n');
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }


    //主函数入口
    public static void main(String[] args) {
        client c = new client();
        c.customer_init();
        try{
            c.sc = new Socket(ip,pocket); //指明服务器端的ip和端口
            c.send(c.cust.getName()+"加入聊天室,大家欢迎");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        c.init_window();
    }

    //界面初始化
    public void init_window(){
        jf = new JFrame();
        jf.setBounds(300, 100, 400, 400);
        jf.setTitle("客户端窗口");
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //聊天记录显示区
        ja = new JTextArea(10, 20);
        ja.setEditable(false);
        //聊天记录输入区
        jt = new JTextField(20);
        //添加窗口监听器,实现发送消息的功能
        jt.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String strSend = jt.getText();
                // 去掉空格判断长度是否为空
                if (strSend.trim().length() == 0) {
                    return;
                }
                //客户端信息strSend发送到服务器上
                jt.setText("");
                ja.append("我说:"+strSend+'\n');
                send(strSend);
                //多线程接受来自服务器的消息
                new Thread(new Receive()).start();
            }
        });
        jf.add(ja, BorderLayout.CENTER);
        jf.add(jt,BorderLayout.SOUTH);
        jf.setVisible(true);
    }


    //多线程的内部类,用以接受服务器的消息
    class Receive implements Runnable {
        @Override
        public void run() {
            try {
                while (true) {
                    InputStream ips = sc.getInputStream();
                    int len;
                    byte[] b = new byte[1024];
                    String str = null;
                    while((len=ips.read(b))!=-1){
                        str = new String(b);
                        //通讯消息
                        ja.append(str+'\n');
                    }
                }
            } catch (SocketException e) {
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}