服务端和单客户端通信

注意事项:如果服务端或者客户端采用read() 一个字节这种读取数据,只要另一方没有关闭连接,read是永远读取不到-1,会陷入死循环中;

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

解决方法:加上一个判断,程序员自己跳出循环,比如在while循环中,加上

if(strbuilder.indexOf("\n") > 0){//存在消息结束标志
    break;
}

  

服务端代码

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket server = new ServerSocket(8080);
            Socket socket = server.accept();
            System.out.println("客户端连接成功:"+server.getInetAddress().getHostAddress());

            BufferedReader bufRead = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String s = bufRead.readLine();
            System.out.println("message="+s);


            BufferedWriter bufwrite = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bufwrite.write("你好我是服务端\n");
            bufwrite.flush();

            bufwrite.close();
            bufRead.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
} 

客户端代码

import java.io.*;
import java.net.Socket;

public class client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",8080);
            BufferedWriter bufWrite = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //如果服务器使用readline来读取数据,那么发送的数据后面必须加上\n;
            bufWrite.write("你好我是客户端\n");
            bufWrite.flush();


            //PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
            //ps.println("dddd");
            //ps.flush();

            BufferedReader bufread = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(bufread.readLine());

            //ps.close();
            bufWrite.close();
            bufread.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  

服务器和多客户端通信

 即采用多线程的方式进行处理任务

服务端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    public static void main(String[] args) {
        try {
            ExecutorService es = Executors.newFixedThreadPool(4);
            ServerSocket server = new ServerSocket(8080);
            while (true){
                Socket socket = server.accept();
                System.out.println("有客户端连接");
                es.execute(new ServerHandle(socket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class ServerHandle implements Runnable{
    private Socket socket;
    public ServerHandle(Socket socker){
        this.socket = socker;
    }
    @Override
    public void run() {
        BufferedReader bufRead = null;
        try {
            bufRead = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
            char[] chars = new char[1024];
            StringBuilder strbuilder = new StringBuilder();
            int len=-1;
            while ((len=bufRead.read(chars))!=-1){
                strbuilder.append(new String(chars),0,len);
                if(strbuilder.indexOf("\n") > 0){//存在消息结束标志
                    break;
                }
            }
            System.out.println("message="+ strbuilder);
            BufferedWriter bufwrite = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bufwrite.write("已经收到你的信息:"+strbuilder+"\n");
            bufwrite.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

客户端

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class client {
    public static void main(String[] args) {
        try {
            Socket socket = new Socket("127.0.0.1",8080);
            BufferedWriter bufWrite = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //如果服务器使用readline来读取数据,那么发送的数据后面必须加上\n;
            Scanner input = new Scanner(System.in);
            System.out.println("输入一个发送的信息");
            String x = input.next();
            bufWrite.write(x+"\n");
            bufWrite.flush();

            BufferedReader bufread = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(bufread.readLine());

            bufWrite.close();
            bufread.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

 

多客户端之间的通信

Server端

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {
    public static void main(String[] args) {
        //保存所有的处理 用户请求连接的 线程
        Vector<UserRequestHandle> vector = new Vector<>();
        ExecutorService es =  Executors.newFixedThreadPool(4);
        try {
            ServerSocket server  =  new ServerSocket(8080);
            System.out.println("服务器已经启动.......");
            while (true){
                Socket socket = server.accept();
                UserRequestHandle user = new UserRequestHandle(socket,vector);
                vector.add(user);
                es.execute(user);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class UserRequestHandle implements Runnable{
    private String name;//客户端的名字(唯一),可以绑定用户对象(唯一);
    private ObjectInputStream ois;
    private ObjectOutputStream oos;
    private Socket socket;
    private Boolean flag=true;
    private Vector<UserRequestHandle> verctor;
    public UserRequestHandle(Socket socket,Vector<UserRequestHandle> verctor){
        this.socket = socket;
        this.verctor = verctor;
    }
    @Override
    public void run() {
        try {
            ois = new ObjectInputStream(socket.getInputStream());
            oos = new ObjectOutputStream(socket.getOutputStream());
            while (flag){
                Message message = (Message) ois.readObject();
                int mes = message.getType();
                switch (mes){
                    case MessageType.type_login:{
                        name = message.getFrom(); //表示给当前的线程取一个名字;
                        message.setMessage("欢迎登录"+message.getFrom());
                        oos.writeObject(message);
                        break;
                    }
                    case MessageType.type_send:{
                        String to_user = message.getTo();
                        String to_user_message = message.getMessage();
                        for (int i = 0; i < verctor.size(); i++) {
                            if (verctor.get(i).name==null|to_user==null){
                                continue;
                            }
                            if (verctor.get(i).name.equals(to_user)&&!to_user.equals(this.name)){
                                System.out.println("消息已经正在发送给对方.....");
                                message.setFrom(name);
                                message.setMessage(to_user_message);
                                verctor.get(i).oos.writeObject(message);
                                break;
                            }
                        }
                    }

                }
            }
            ois.close();
            oos.close();
        } catch (IOException|ClassNotFoundException e) {
            e.printStackTrace();
            return;
        }catch (Exception e){
        }
    }
}

 客户端

import java.io.*;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class client {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        try {
            Socket socket = new Socket("127.0.0.1",8080);
            System.out.println("连接服务器成功......");
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            //第一步先登录;
            System.out.println(MessageType.type_login+","+MessageType.type_send);
            System.out.println("输入用户名");
            String name = input.next();
            oos.writeObject(new Message(name,null,MessageType.type_login,null));
            Message message = (Message) ois.readObject();
            System.out.println(message.getMessage());
            
            //创建一个单线程从socket中循环取出消息(只读)
            ExecutorService receve_message = Executors.newSingleThreadExecutor();
            receve_message.execute(new ReceveMessage(ois));

            //不断给服务发送消息(只写)
            while (true){
                System.out.println("输入要发送消息的用户名");
                String to_user = input.next();
                System.out.println("输入消息");
                String to_user_message = input.next();
                oos.writeObject(new Message(name,to_user,MessageType.type_send,to_user_message));
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class ReceveMessage implements Runnable{
    private ObjectInputStream ois;
    public ReceveMessage(ObjectInputStream ois){
        this.ois = ois;
    }
    @Override
    public void run() {
        try {
            while (true){
                Message message = (Message) this.ois.readObject();
                System.out.println("["+message.getFrom()+"]"+":"+message.getMessage());
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

message信息对象

import java.io.Serializable;


public class Message implements Serializable {
    private String from;  //发送消息的人(以后可以用ip来处理)
    private String to;    //发送消息给谁(以后可以用ip来处理)
    private int type; //int type  消息的类型(是登录还是进行消息的发送)
    private String message;//消息的内容
    public Message(String from, String to, int type, String message) {
        this.from = from;
        this.to = to;
        this.type = type;
        this.message = message;
    }
    public String getFrom() {
        return from;
    }
    public String getTo() {
        return to;
    }
    public int getType() {
        return type;
    }
    public String getMessage() {
        return message;
    }
    public void setFrom(String from) {
        this.from = from;
    }
    public void setTo(String to) {
        this.to = to;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

MessageType表示配置文件

public class MessageType {
    public static final int type_login = 1;//消系中有type_login表示需要登录
    public static final int type_send = 2; //消息中有type_send表示该消息为发送
}

  

 

UDP服务端和客户端通信

服务端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Server {
    public static void main(String[] args) throws IOException {
        byte[] bs = new byte[500];
        DatagramPacket p1 = new DatagramPacket(bs, bs.length);
        //创建数据报套接字
        DatagramSocket socket_B = new DatagramSocket(10010);
        //接收数据报包
        socket_B.receive(p1);
        System.out.println(new String(bs, 0, p1.getLength()));

        byte[] send_msg = "我是服务端,我已经收到你的消息".getBytes();
        InetAddress desIp = p1.getAddress(); //获取对方的ip
        int dedport = p1.getPort();
        //数据包中包括数据,数据长度,对方的ip和绑定的端口
        DatagramPacket p = new DatagramPacket(send_msg, send_msg.length, desIp, dedport);
        socket_B.send(p);
        socket_B.close();
    }
}

客户端

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class client {
    public static void main(String[] args) throws IOException {

        byte[] send_bs = "我是客户端,我给你发送了一些数据".getBytes();//要发的信息内容
        //创建数据报,里面包括  数据和数据长度  对方的ip地址 和 对方的端口,
        DatagramPacket p1 = new DatagramPacket(send_bs, send_bs.length,InetAddress.getByName("127.0.0.1"),10010);
        //创建数据报套接字,绑定端口
        DatagramSocket socket = new DatagramSocket(8080);
        socket.send(p1);

        //用数组接收数据报包
        byte[] rece_msg = new byte[500];
        DatagramPacket p = new DatagramPacket(rece_msg, rece_msg.length);
        socket.receive(p);//数据量如果多,可以使用while循环
        System.out.println(new String(rece_msg, 0, p.getLength()));
        //关闭套接字
        socket.close();
    }
}

  

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄