java网络编程总结

java网络编程总结,第1张

文章目录
      • 一、IP地址
        • 1、网页编程:B/S架构(Browser/Server(浏览器/服务器))
        • 2、客户端服务器编程:C/S架构(Client/Server(客户端/服务器))
        • 3、InetAddress类
        • 4、端口
        • 5、InetSocketAddress类
      • 二、TCP实现聊天
      • 三、TCP实现文件上传
      • 四、UDP实现客户端向服务器发送信息
      • 五、UDP实现客户端与服务器的简单聊天系统
      • 六、URL
        • 1、URL类
        • 2、使用url下载网站上的资源

一、IP地址 1、网页编程:B/S架构(Browser/Server(浏览器/服务器)) 2、客户端服务器编程:C/S架构(Client/Server(客户端/服务器))

具体IPV4,IPV6的区别请看:https://zhuanlan.zhihu.com/p/271708071

3、InetAddress类

import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 1. @Author marryandy
 2. @date 2022/4/21 16:08
 3. @Version 1.0
 4. @Description
 */
public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
            System.out.println(inetAddress1);
            InetAddress inetAddress2 = InetAddress.getByName("Localhost");
            System.out.println(inetAddress2);
            InetAddress inetAddress3 = InetAddress.getLocalHost();
            System.out.println(inetAddress3);

            //查询网络IP地址
            InetAddress inetAddress4 = InetAddress.getByName("www.baidu.com");
            System.out.println(inetAddress4);

            //输出规范的IP
            System.out.println(inetAddress4.getCanonicalHostName());
            //获得IP地址
            System.out.println(inetAddress4.getHostAddress());
            //获得域名或者自己电脑的名字
            System.out.println(inetAddress4.getHostName());
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }


    }
}

4、端口

详见:https://note.youdao.com/s/ZV5G7Vbw

5、InetSocketAddress类

import java.net.InetSocketAddress;

/**
 * @Author marryandy
 * @date 2022/4/21 17:44
 * @Version 1.0
 * @Description
 */
public class TestInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress inetSocketAddress1 = new InetSocketAddress("127.0.0.1",8080);
        System.out.println(inetSocketAddress1);

        InetSocketAddress inetSocketAddress2 = new InetSocketAddress("localhost",8080);
        System.out.println(inetSocketAddress2);

        System.out.println(inetSocketAddress1.getAddress());
        //HostName 可以在host文件下进行修改
        System.out.println(inetSocketAddress1.getHostName());
        System.out.println(inetSocketAddress1.getPort());
    }
}

二、TCP实现聊天

通信协议基本知识,详见:https://note.youdao.com/s/11qoeUvF

//客户端
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

/**
 * @Author marryandy
 * @date 2022/4/21 19:59
 * @Version 1.0
 * @Description
 */
public class TcpClientDemo01 {
    public static void main(String[] args) {

        Socket socket = null;
        OutputStream os = null;

        try {
            Scanner sc = new Scanner(System.in);
            //1.知道服务器的地址
           InetAddress serverIp =  InetAddress.getByName("127.0.0.1");
            //2.端口号
            int port = 9999;
            //3.创建一个socket连接
            while(true){
                socket = new Socket(serverIp,port);
                //4.发送消息IO流
                os =  socket.getOutputStream();

                String str = sc.nextLine();
                os.write(str.getBytes());
                if(str.equals("bye")){
                    break;
                }
//                os.flush();
                os.close();
            }


        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally{
            //关闭资源:从下向上关闭,先开后关
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}
//服务端
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author marryandy
 * @date 2022/4/21 19:59
 * @Version 1.0
 * @Description
 */
public class TcpServerDemo01 {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream inputStream = null;
        ByteArrayOutputStream baos = null;

        try {
            //1.设置一个地址
            serverSocket = new ServerSocket(9999);
            //2.等待客户端连接过来,socket对象接到了以后,客户端和服务端的socket就是同一个了
            while(true){

                socket = serverSocket.accept();
                //3.读取客户端的消息
                inputStream = socket.getInputStream();
                //管道流

                baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while ((len = inputStream.read(buffer)) != -1){
                    baos.write(buffer,0,len);
                }

                System.out.println(baos.toString());
                if (baos.toString().equals("bye")){
                    break;
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }finally{
            //关闭资源:从下向上关闭,先开后关
            if(baos != null){
                try {
                    baos.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if(inputStream != null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

            if(serverSocket != null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

        }

    }
}

博主在修改这个程序的时候,发现程序运行到while ((len = inputStream.read(buffer)) != -1)这个循环的时候,只执行一次循环中的内容。百思不得其解,查询API,如下图:

最后发现,inputStream.read()方法一直在阻塞,它并不知道客户端已经发送完毕了,还在等待,需要在客户端把输出流关闭(os.close();),强行告诉服务器已经发送完毕,一般传送文件不会发生这种阻塞,详见:https://blog.csdn.net/qq_34756209/article/details/114689034

三、TCP实现文件上传
//客户端
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

/**
 * @Author marryandy
 * @date 2022/4/21 21:05
 * @Version 1.0
 * @Description
 */
public class TcpClientDemo02 {
    public static void main(String[] args) throws Exception {
        //1.创建一个socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();
        //3.文件流
        FileInputStream fis = new FileInputStream(new File("11111.png"));
        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer)) != -1){
            os.write(buffer,0,len);
        }
        //通知服务器,传输完毕
        socket.shutdownOutput();

        //确定服务器接收完毕,才能够断开连接
        InputStream is = socket.getInputStream();
        //String byte[]
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while((len2 = is.read(buffer2)) != -1){
            baos.write(buffer2,0,len2);
        }
        System.out.println(baos.toString());
        //5.关闭资源
        baos.close();
        is.close();
        fis.close();
        socket.close();
        
    }
}
//服务端
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author marryandy
 * @date 2022/4/21 21:06
 * @Version 1.0
 * @Description
 */
public class TcpServerDemo02 {
    public static void main(String[] args) throws IOException {
        //1.创建一个端口
        ServerSocket serverSocket = new ServerSocket(9000);
        //2.监听客户端的连接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待客户端连接,如果不通知
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //4.文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.png"));
        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

        //通知客户端接收完毕
        OutputStream os = socket.getOutputStream();
        os.write("我接收完毕了".getBytes());

        //5.关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();

    }
}


四、UDP实现客户端向服务器发送信息
//客户端
package chat;

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

/**
 * @Author marryandy
 * @date 2022/5/5 20:52
 * @Version 1.0
 * @Description
 */
public class UdpSenderDemo01 {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8888);
        //准备数据:控制台读取 System.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        while(true){
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress("localhost",6666));
            socket.send(packet);
            if (data.equals("bye")){
                break;
            }
        }

        socket.close();
    }
}

套接字就是发送方或接收方的地址

//服务端
package chat;

import java.io.IOException;
import java.io.InputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * @Author marryandy
 * @date 2022/5/5 20:53
 * @Version 1.0
 * @Description
 */
public class UdpReceiveDemo02 {
    public static void main(String[] args) throws Exception {
    //DatagramSocket相当于接收点的地址
        DatagramSocket socket = new DatagramSocket(6666);

        while(true){
            //准备接收包裹
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container,0,container.length);
            socket.receive(packet);//阻塞式接收包裹
            //断开连接
            byte[] data = packet.getData();
/*          
			String receiveData = new String(data, 0, data.length);
			不能使用这个data.length,详见下面的解释
*/
            String receiveData = new String(data, 0, packet.getLength());
            System.out.println(receiveData);

            if(receiveData.equals("bye")){
                break;
            }

        }
        //准备接收包裹


    }
}


有个问题,就是客户端输入bye后,客户端程序停止运行,但是服务端,不停止运行。经过debug,发现,receiveData 的长度为1024惊呆了,这怎么可能相等,楼主现在只想到用写个for循环来字符串截取,想使用流技术来实现,无奈忘光了,等博主复习完再来!!

查到了,可以使用packet.getLength()方法,就是接收数据的长度

五、UDP实现客户端与服务器的简单聊天系统

分别在客户端和服务端使用两个线程来 *** 作,使他们既可以发送信息也可以接收信息。

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;

/**
 * @Author marryandy
 * @date 2022/5/6 14:16
 * @Version 1.0
 * @Description
 */
public class TalkSend implements Runnable {
    DatagramSocket socket = null;
    BufferedReader reader = null;
    private int fromPort;
    private String toIp;
    private int toPort;


    public TalkSend(int fromPort, String toIp, int toPort) {
        this.fromPort = fromPort;
        this.toIp = toIp;
        this.toPort = toPort;

        try {
             socket = new DatagramSocket();
             reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }



    @Override
    public void run() {
        while(true){
            try {
                    String data = reader.readLine();
                    byte[] datas = data.getBytes();
                    DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIp,this.toPort));
                    socket.send(packet);
                    if (data.equals("bye")){
                        break;
                    }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }

        socket.close();
    }
}
package chat;

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

/**
 * @Author marryandy
 * @date 2022/5/6 14:33
 * @Version 1.0
 * @Description
 */
public class TalkReceive implements Runnable{
    DatagramSocket socket = null;
    private int port;
    private String msgFrom;

    public TalkReceive(int port,String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void run() {

        while(true){
            try {
                //准备接收包裹
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container,0,container.length);
                socket.receive(packet);//阻塞式接收包裹

                //断开连接
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length);

                System.out.println(msgFrom + ":" + receiveData);

                if(receiveData.equals("bye")){
                    break;
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
        //准备接收包裹


    }
}
package chat;

/**
 * @Author marryandy
 * @date 2022/5/6 14:55
 * @Version 1.0
 * @Description
 */
public class TalkStudent {
    public static void main(String[] args) {
        //开启两个线程:他既有可能是接收端,也有可能是发送端
        new Thread(new TalkSend(7777,"localhost",9999)).start();

        new Thread(new TalkReceive(8888,"老师")).start();
    }
}
package chat;

/**
 * @Author marryandy
 * @date 2022/5/6 14:59
 * @Version 1.0
 * @Description
 */
public class TalkTeacher {
    public static void main(String[] args) {
        //开启两个线程:他既有可能是接收端,也有可能是发送端,自己发送的端口无所谓
        new Thread(new TalkSend(5555,"localhost",8888)).start();

        new Thread(new TalkReceive(9999,"学生")).start();
    }
}

六、URL

1、URL类

package URL;

import java.net.MalformedURLException;
import java.net.URL;

/**
 * @Author marryandy
 * @date 2022/5/6 15:37
 * @Version 1.0
 * @Description
 */
public class URLDemo01 {
    //http://localhost:8080/MarryAndy/hello.txt
    public static void main(String[] args) {
        try {
            URL url = new URL("http://locolhost:8080/helloword/index.jsp?username=MarryAndy&password=123");
            System.out.println(url.getProtocol());//协议
            System.out.println(url.getHost());//主机IP
            System.out.println(url.getPort());//端口
            System.out.println(url.getPath());//文件
            System.out.println(url.getFile()); //文件全路径
            System.out.println(url.getQuery());//参数
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        }

    }
}

2、使用url下载网站上的资源
package URL;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
 * @Author marryandy
 * @date 2022/5/6 15:50
 * @Version 1.0
 * @Description
 */
//使用url下载网站上的资源
public class URLDown {
    public static void main(String[] args) throws Exception {
        //1.下载地址
        URL url = new URL("https://m704.music.126.net/20220506171202/095bc95b33fbf5270ceeb7d7be16554f/jdyyaac/obj/w5rDlsOJwrLDjj7CmsOj/14120501060/f1bb/04b6/3118/89db17878551efbf4f1c7f3268616d08.m4a?authSecret=00000180988d0c2c07300aa4638a1861");
        //2.连接到这个资源 http,网络上一切都是流
        HttpURLConnection urlconnection = (HttpURLConnection) url.openConnection();
        InputStream inputStream = urlconnection.getInputStream();

        FileOutputStream fos = new FileOutputStream("这个年纪.m4a");
        byte[] buffer = new byte[1024];
        int len;
        while((len = inputStream.read(buffer)) != -1){
            fos.write(buffer,0,len );//写出这个数据
        }
        fos.close();
        inputStream.close();
        urlconnection.disconnect();//断开连接



    }
}

详见:https://note.youdao.com/s/1VIzGeqb

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/877140.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存