Tcp与Udp发送消息 以及模仿多线程聊天

Tcp与Udp发送消息

TCP 建立连接三次握手;断开连接 四次挥手

类似于打电话,需要对方同意接通,才能通话

  1. 传输文本

(1)客户端

package tcp.demo1;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class TcpClient {
    
    
    public static void main(String[] args) {
    
    
        Socket socket=null;
        OutputStream os=null;
        try {
    
    
            //1.要知道服务端插槽,知道服务端端口号
            InetAddress serverIp = InetAddress.getByName("127.0.0.1");
            int port=999;
            //2.创建一个socket连接 连接需要服务端IP地址和服务端端口号
            socket = new Socket(serverIp,port);
            //3.发送消息 IO流
            os =socket.getOutputStream();
            os.write("你好".getBytes());//数组

        } catch (Exception e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if (os != null) {
    
    
                try {
    
    
                    os.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (socket != null) {
    
    
                try {
    
    
                    socket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

(2)服务端

package tcp.demo1;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TcpServer {
    
    
    public static void main(String[] args) {
    
    
        ByteArrayOutputStream baos=null;
        InputStream is=null;
        Socket socket=null;
        ServerSocket serverSocket=null;
        //1.我得有一个地址
        try {
    
    //开启客户端插槽
            serverSocket = new ServerSocket(999);
            //2.等待客户端连接进来
            while(true){
    
    
            socket=serverSocket.accept();
            //3.读取客户端的消息----与客户端消息对应
            is=socket.getInputStream();
            /*有个弊端 如果传输信息超过1024,会乱码
            byte[] buffer=new byte[1024];//建一个数组管道
            int len;用len接收消息
            while((len=is.read(buffer))!=-1){//说明管道有值
            String msg=new String(buffer,0,len);
            System.out.println(msg); }*/
            //管道流
            baos=new ByteArrayOutputStream();
            byte[] buffer=new byte[1024];//管道大小
            int len;//用len接收消息
            while((len=is.read(buffer))!=-1) {
    
    //说明管道有值
                baos.write(buffer,0,len);//读进来,写出去
            }
            System.out.println(baos.toString());}
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
        finally {
    
    
            //关闭资源  先开后关;
            if (baos != null) {
    
    
                try {
    
    
                    baos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (is != null) {
    
    
                try {
    
    
                    is.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (socket != null) {
    
    
                try {
    
    
                    socket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (serverSocket != null) {
    
    
                try {
    
    
                    serverSocket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

  1. 传输文件

(1)客户端

package tcp.demo2;

import org.omg.PortableInterceptor.INACTIVE;

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

public class TcpClientfile {
    
    

    public static void main(String[] args) throws Exception {
    
    
        //1.创建一个Socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),999);
        //2.创建输出流
        OutputStream os=socket.getOutputStream();
        //3.文件流读取
        FileInputStream fis = new FileInputStream(new File("my.png"));
       //4.写出文件
        byte[] buffer=new byte[1024];//管道大小
        int len;//用len接收消息
        while((len=fis.read(buffer))!=-1) {
    
    //说明管道有值
            os.write(buffer,0,len);//读进来,写出去
        }
        //通知服务器,我已经结束
        socket.shutdownOutput();
        //确定服务端接收完毕
        InputStream inputStream=socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        byte[] buffer1=new byte[2014];//管道大小
        int len1;//用len接收消息
        while((len1=inputStream.read(buffer1))!=-1) {
    
    //说明管道有值
            bos.write(buffer1,0,len1);//读进来,写出去
        }
        System.out.println(bos.toString());
        //5.关闭资源
        bos.close();
        inputStream.close();
        fis.close();
        os.close();
        socket.close();
    }


}

(2)服务端

package tcp.demo2;

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

public class TcpServerfile {
    
    
    public static void main(String[] args) throws IOException {
    
    
        //1.创建服务
        ServerSocket serverSocket=new ServerSocket(999);
        //2.监听客户端连接,阻塞式监听
        Socket socket=serverSocket.accept();
        //3.获取输入流
        InputStream is=socket.getInputStream();
        //4.文件输出
        FileOutputStream fos=new FileOutputStream(new File("recive.png"));
        byte[] buffer=new byte[1024];//管道大小
        int len;//用len接收消息
        while((len=is.read(buffer))!=-1) {
    
    //说明管道有值
            fos.write(buffer,0,len);//读进来,写出去
        }
        //确定客户端输出完毕
        OutputStream ops=socket.getOutputStream();
        ops.write("接受完毕".getBytes());
        //关闭资源
        ops.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }

}

UDP 连接不用对方同意 需要知道对方已经开的端口即可

类似于发短信 不用对方同意 知道对方联系方式就可以

(1)发送端

package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Udpsend {
    
    
    //发送端
    public static void main(String[] args) throws Exception {
    
    
        //1.建立socket连接 相当于连接管道
        DatagramSocket socket = new DatagramSocket();
        //2.建立包
        InetAddress address=InetAddress.getByName("localhost");
        String data="Hello word";
        int port=9090;
        //第一个参数(内容);第二三个参数(从哪开始,到哪结束);第四个参数(地址);第五个参数(端口号)
        DatagramPacket datagramPacket = new DatagramPacket(data.getBytes(), 0, data.getBytes().length, address, port);
        //3.发送包
        socket.send(datagramPacket);
        //4.关闭资源
        socket.close();
    }
}

(2)接收端

package udp;


import java.net.DatagramPacket;
import java.net.DatagramSocket;


public class Udpreceive {
    
    
    //接收端
    public static void main(String[] args) throws Exception {
    
    
        //1.开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        //2.接受数据包
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length);
        socket.receive(packet);//阻塞接收
        //3.可以输出看一下
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(),0,packet.getLength()));
        //4.关闭连接
        socket.close();
    }
}

多线程聊天

(1)发送端

package chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;

public class Udpchatse implements Runnable{
    
    
    DatagramSocket socket=null;
    BufferedReader reader=null;
    private int fromport;
    private String tpIp;
    private int toport;

    public Udpchatse(int fromport, String tpIp, int toport) {
    
    
        this.fromport = fromport;
        this.tpIp = tpIp;
        this.toport = toport;
        try {
    
    
            socket = new DatagramSocket(fromport);
        } catch (SocketException e) {
    
    
            e.printStackTrace();
        }
        reader = new BufferedReader(new InputStreamReader(System.in));
    }

    @Override
    public void run() {
    
    
        //准备数据,从控制台输入

        while (true){
    
    
            try {
    
    
                String data=reader.readLine();//读取数据
                byte[] bytes = data.getBytes();//转换
                //打包
                DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length, new InetSocketAddress(tpIp,toport));
                //发送
                socket.send(packet);
                if(data.trim().equals("bye")){
    
    
                    break;
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        socket.close();
    }
}

(2)接收端

package chat;

import sun.awt.windows.WPrinterJob;

import javax.swing.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class Udpchatre implements Runnable{
    
    
    DatagramSocket socket=null;
    private int port;
    private String fromName;

    public Udpchatre(int port, String fromName) {
    
    
        this.port = port;
        this.fromName = fromName;
        try {
    
    
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
    
    
        while (true){
    
    
            try {
    
    
                byte[] bytes = new byte[1024];//准备管道接收数据
                // 把管道的数据打包
                DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);
                //接受包
                socket.receive(packet);
                //断开连接
                byte[] data=packet.getData();
                String s = new String(data,0, data.length);
                System.out.println(fromName+":"+s);
                if (s.trim().equals("bye")){
    
    
                    break;
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        //关闭资源
        socket.close();
    }
}

(3)学生端

package chat;

public class TestStudent {
    
    
    public static void main(String[] args) {
    
    
        new Thread(new Udpchatse(2222,"localhost",9999)).start();
        new Thread(new Udpchatre(3333,"老师")).start();
    }
}

(4)教师端

package chat;

public class TestTeacher {
    
    
    public static void main(String[] args) {
    
    
        new Thread(new Udpchatse(4444,"localhost",3333)).start();
        new Thread(new Udpchatre(9999,"学生")).start();
    }
}

xinyue Day3

猜你喜欢

转载自blog.csdn.net/qq_47735503/article/details/110584468