网络编程基础-java-TCP/UDP-BIO

概述

  • 计算机网络:是指将位置不同计算机,通过通信线路连接起来,在网络操作系统,网络协议…协调下实现网络资源共享。
  • 网络编程:在网路通信协议下,实现网络互联的不同的计算机可以进行数据互联。
  • 网络编程三要素:
    1):端口号
    2):IP地址
    3):通行协议
    关于计算机网络基础知识,例如IP地址的划分,类型,TCP/IP讲解…在我的另外一篇博客有详细讲解:
    计算机网络 知识点总结
    这篇博客主要讲解网络编程。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

InetAddress

public class InetAddress extends Object implements Serializable
此类表示Internet协议(IP)地址。

此类没有构造方法

  • 这里说三个方法:
    1)
    public static InetAddress getAllByName(String host)
    throws UnknownHostException
    确定主机名称的IP地址。
    主机名称可以是机器名称,例如“ java.sun.com ”或其IP地址的文本表示。 如果提供了文字IP地址,则只会检查地址格式的有效性。
    2)public String getHostAddress()返回文本显示中的IP地址字符串。
    3)public String getHostName()获取此IP地址的主机名。
InetAddress byName = InetAddress.getByName("198.16.1.66");
        System.out.println(byName.getHostName());

UDP

在这里插入图片描述

  • DatagramPacket
    public final class DatagramPacket extends Object
    该类表示数据报包。
    数据报包用于实现无连接分组传送服务。 仅基于该数据包中包含的信息,每个消息从一台机器路由到另一台机器。 从一台机器发送到另一台机器的多个分组可能会有不同的路由,并且可能以任何顺序到达。 包传送不能保证。
    DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
    构造用于发送长度的分组数据报包 length具有偏移 ioffset指定主机上到指定的端口号。
    参数
    buf - 数据包数据。
    offset - 分组数据偏移量。
    length - 分组数据长度。
    address - 目的地址。
    port - 目的端口号。

  • DatagramSocket
    public class DatagramSocket
    extends Object
    implements Closeable
    此类表示用于发送和接收数据报数据包的套接字。

public DatagramSocket(int port) throws SocketException
构造数据报套接字并将其绑定到本地主机上的指定端口。 套接字将被绑定到wildcard地址,一个由内核选择的IP地址。

public void send(DatagramPacket p) throws IOException
从此套接字发送数据报包。 DatagramPacket包括指示要发送的数据,其长度,远程主机的IP地址和远程主机上的端口号的信息。

public void receive(DatagramPacket p) throws IOException
从此套接字接收数据报包当此方法返回时, DatagramPacket的缓冲区将填充接收到的数据。 数据包数据包还包含发送者的IP地址和发件人机器上的端口号。

  • UDP发送数据代码:
    在这里插入图片描述
public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket();
        InetAddress byName = InetAddress.getByName("198.16.1.66");//IP地址
        int port=10086;//端口号
        byte []bytes="hahah".getBytes();//要发送的数据
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length,byName,port);//打包
        ds.send(dp);//发送
        ds.close();//关闭
    }
  • UDP发送数据代码
    在这里插入图片描述
public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket(10086);
        byte[]bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes,1024);
        ds.receive(dp);
        byte[] data = dp.getData();
        String datab=new String(data);
        System.out.println(datab);
        ds.close();//不许关闭 不然在缓冲流中
    }
  • UDP通信练习
    *在这里插入图片描述
public class UDPsend {
    public static void main(String[] args) throws IOException {
        DatagramSocket ds=new DatagramSocket();
        DatagramPacket dp;
        int port=10086;
        InetAddress ipaddress=InetAddress.getByName("192.168.1.7");
        Scanner in=new Scanner(System.in);
        while (true){
            System.out.println("输入");
            String s=in.nextLine();
            if (s.equals("hello")){
                break;
            }
            byte []bytes=s.getBytes();
            dp=new DatagramPacket(bytes,bytes.length,ipaddress,port);
            ds.send(dp);
        }
        ds.close();
    }
}
public class UDPrecive {
    public static void main(String[] args) throws IOException {
        int report=10086;
        DatagramSocket ds=new DatagramSocket(report);
        byte[] bytes=new byte[1024];
        DatagramPacket dp=new DatagramPacket(bytes,bytes.length);
        while (true){
            ds.receive(dp);
            byte[] getby=dp.getData();
            int len=getby.length;//这里是因为上面new byte[1024],如果有多的空白格子就不让输出了
            System.out.println("数据是"+new String(getby,0,len));
        }
    }
}

TCP

在这里插入图片描述

  • TCP发送数据
    在这里插入图片描述
public static void main(String[] args) throws IOException {
        int port=10086;
        InetAddress ipadd=InetAddress.getByName("192.168.1.7");
        Socket socket=new Socket(ipadd,port);
         OutputStream bos=  socket.getOutputStream();
         bos.write("wwww".getBytes());
         bos.close();
    }
  • TCP接受数据
    在这里插入图片描述
public static void main(String[] args) throws IOException {
        int port=10086;
        ServerSocket serverSocket=new ServerSocket(port);
        Socket socket=serverSocket.accept();
        InputStream bis=socket.getInputStream();
        int len;
        byte []bytes=new byte[1024];
        while ((len=bis.read(bytes))!=-1){
            System.out.println(new String(bytes));

        }
    }
  • 练习1:服务器端给出反馈
    在这里插入图片描述
public class TCPcliet {
    public static void main(String[] args) throws IOException {
        int port =10086;
        InetAddress ipadd=InetAddress.getByName("192.168.1.7");
        Socket socket=new Socket(ipadd,port);
        //传数据
        OutputStream ops = socket.getOutputStream();
        String senfs="我想连接";
        ops.write(senfs.getBytes());
        //接受反馈
        InputStream ism = socket.getInputStream();
        byte []bytes=new byte[1024];
        ism.read(bytes);
        System.out.println(new String(bytes));

        socket.close();

    }
}
public class TCPserver {
    public static void main(String[] args) throws IOException {
        int port=10086;
        InetAddress ipadd=InetAddress.getByName("192.168.1.7");
        ServerSocket serverSocket=new ServerSocket(port);
        //得到接受的套接字
        Socket socket =serverSocket.accept();
        //读出数据
        InputStream ism = socket.getInputStream();
        int len;
        byte []bytes=new byte[1024];
        //阻塞!!!!!
        while ((len=ism.read(bytes))!=-1){
            System.out.println(new String(bytes));
        }
        //给出反馈
        OutputStream osm = socket.getOutputStream();
        osm.write("收到".getBytes());

        socket.close();
        serverSocket.close();
    }
}

发生阻塞代码

  • 客户端从文件中读数据传给服务器端
    在这里插入图片描述
    这个练习我会给出两种代码,第一种是错误的,会发生阻塞
    代码一:
public class TCPcliet {
    private  int port=10086;
    private String ip="192.168.1.7";
    private Socket socket;
    private BufferedWriter bwe;
    private BufferedReader bre;

    public TCPcliet() {//建立连接
        try {
            socket=new Socket(ip,port);
            startclient(socket);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void startclient(Socket socket){
        try {
            //发送数据
            bre=new BufferedReader(new FileReader("D://filetest//readw.txt"));
            bwe=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            String str;
            while ((str=bre.readLine())!=null){
                bwe.write(str);
                bwe.flush();
            }
            System.out.println("1111");//运行到这给了个标识符
            //接受反馈
            BufferedReader breserver=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String strk;
            while ((strk=breserver.readLine())!=null){
                System.out.println(strk);
            }
            bre.close();
            socket.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        new TCPcliet();
    }
}
public class TCPserver {
    private int port=10086;
    private Socket getsocket;
    private ServerSocket serverSocket;
    private BufferedReader bre;
    private BufferedWriter bwe;

    public TCPserver() {
        try {//创建连接
            ServerSocket serverSocket=new ServerSocket(port);
            getsocket=serverSocket.accept();
            startserver(getsocket);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void startserver(Socket socket){
        try {
            bre=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            String str;
            while ((str=bre.readLine())!=null){
                System.out.println(str);
            }
            System.out.println("222");//运行到这给了个标识符
            //给出反馈
            bwe=new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bwe.write("老子收到了886");
            bwe.flush();
            bwe.close();
            socket.close();
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    public static void main(String[] args) throws IOException {
       new TCPserver();
    }
}

大家注意我服务器端和客户端中间有两个输出
System.out.println(“1111”);//运行到这给了个标识符(客户端)
System.out.println(“222”);//运行到这给了个标识符(服务器端)
上面这段代码输出是这样的:
客户端(TCPclient):
在这里插入图片描述
服务器端(TCPserver)
在这里插入图片描述
我们发现两个都没有暂停都停下不动了!而客户端只输出了一个111.
因该是客户端把数据给服务器端而服务器给客户一个反馈,但是我们发现在服务器端并没有输出222,这里是发生了阻塞。
while ((str=bre.readLine())!=null){//阻塞了
System.out.println(str);
}
在这段代码服务器端一直在等着读客户发来的数据,虽然客户端那边发完了(输出111能看出),但是服务器端不知到客户端发送完了,一直在等客户端的数据。而在客户端所以一直收不到服务器端反馈
解决方法是让服务器端知道什么时候发完了!!
服务器端这样改:

while ((str=bre.readLine())!=null{//阻塞了
        if(str.equals("完了")){
        break;
        }
            System.out.println(str);
        }

客户端那里只需要在发完数据后在发送一句“完了”。

  • 多线程实现
    在这里插入图片描述
public class TCPcliet {
    private int port=10000;
    private String IP="192.168.1.7";
    private Socket csocket;
    private int count;
    public TCPcliet() {
        try {
            csocket =new Socket(IP,port);
            start(csocket);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    public void start(Socket socket){

            try {
                while (true){
                    //发送文件
                    BufferedReader cbr=
                            new BufferedReader(new FileReader("D://filetest//readw.txt"));
                    BufferedWriter cbw=
                            new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                    String str;
                    while ((str=cbr.readLine())!=null){
                        cbw.write(str);
                        cbw.newLine();
                        cbw.flush();
                    }
                    socket.shutdownOutput();
                    System.out.println("222");
                    //得到反馈
                    BufferedReader getbr=
                            new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String getstr=getbr.readLine();
                    System.out.println("收到回复为"+getstr);
                }

            }catch (IOException e){
                e.printStackTrace();
            }finally {
                try {
                    socket.close();
                }catch (IOException a){
                    a.printStackTrace();
                }
            }


    }
    public void shutdownbuff(){
        try {
            BufferedWriter stopbuff=
                    new BufferedWriter(new OutputStreamWriter(csocket.getOutputStream()));
            stopbuff.write("老子输入完了,你别阻塞等我了");
        }catch (IOException e){
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {
        new TCPcliet();
    }
}
public class TCPserver {
    private int port=10000;
    private ServerSocket serverSocket;


    public TCPserver() {
        try {
            serverSocket =new ServerSocket(port);

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

    public void startserver(){

            try {
                while (true){
                    System.out.println("服务器请求连接");
                    Socket socket = serverSocket.accept();//这里如果一直未接受会发生阻塞
                    //创建线程
                    new Thread(new ThreadServer(socket)).start();
                }



            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                try {
                    serverSocket.close();
                }catch (IOException a){
                    a.printStackTrace();
                }

            }


    }

    public static void main(String[] args) throws IOException{
        new TCPserver().startserver();
    }
}
public class ThreadServer implements Runnable {
    Socket socket;
    public ThreadServer(Socket s) {
        this.socket=s;
    }

    @Override
    public void run() {
        try {
            BufferedReader brsocket=
                    new BufferedReader(new InputStreamReader(socket.getInputStream()));

            String str;
            while ((str=brsocket.readLine())!=null){
                if (str.equals("老子输入完了,你别阻塞等我了")){
                    break;
                }
                System.out.println(str);
            }

            System.out.println("111");
            //给回复
            BufferedWriter bw=
                    new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write("俺收到了");
            bw.flush();




        }catch (IOException e){
            e.printStackTrace();
        }finally {
            try{
                socket.close();
            }catch (IOException e){
                e.printStackTrace();
            }
        }

    }
}
发布了43 篇原创文章 · 获赞 12 · 访问量 1405

猜你喜欢

转载自blog.csdn.net/qq_42411214/article/details/104459455