飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

网络编程基础

时间:2021-12-03  作者:匿名  

基础知识

客户端:指浏览器或者自定义的客户端。

服务端:像Tomcat服务器或者自定义客户端。

域名
域名

域名
域名

TCP/IP

TCP:传输层协议。

IP:网络层协议。

TCP/域名

TCP/UDP

TCP与UDP区别

TCP使用案例:用于RPC接口调用,发送电子邮件等需要可靠性传输的事情。

UDP使用案例:用于视频这类的传输。

相同点:

  • TCP与UDP都是网络层的通信协议,只是通信的协议不同。

不同点:

  • TCP协议在通信前要先通过三次握手的方式建立连接,保证通信的可靠性。而UDP不需要建立连接接可以发送数据包,因此接收方不一定能收到,因此是不可靠的。
  • TCP协议需要建立连接和释放连接,因此传输效率低。而UDP不需要释放资源,因此开销小,速度快。
  • UDP可以进行广播发送,而TCP是点对点通信。
  • TCP在建立连接后可以进行大数据量的传输,而UDP会限制每个数据包的传输大小在64K以内。

TCP/域名

TCP

域名
域名
域名

三次握手

客户端建立连接请求时的三次握手:

第一次握手:客户端向服务端发送syn报文和序号x;

第二次握手:服务端接收到客户端的请求,发送ack=x+1报文,并发送序号y,syn报文。

第三次握手:客户端接收到服务端的请求,发送ack= y+1报文,并发送序号z。

为什么是三次握手而不是二次或者四次五次呢?

因此根据三次握手我们客户端和服务端都可以知道自己发送正常,对方接收正常;而二次握手的话,服务端并不知道自己发送正常,只能知道客户端发送接收正常,自己接收正常,而不知道自己发送正常。而三次握手刚好就满足了这个条件。既然三次握手就满足了,四次五次就会显得多余了,虽然更多次的握手可以更加保证通信的正常,但是正常来说三次握手就能保证通信99%是可靠的,再多次的握手可靠性的提高并不高,意义不大。

三次握手.png

四次挥手

客户端服务端都可以通过四次挥手关闭连接,但一般都是客户端发起四次挥手请求来关闭连接,因为我们服务端一般是24小时在线服务的。

以客户端发起断开连接为例:

客户端告诉服务端我要断开连接了。

服务端相应客户端说我收到你的断开连接请求了。

服务端断开连接,并发送请求告诉客户端我和你断开连接了。

客户端收到断开连接请求断开了连接,并发送确认断开的请求告诉服务我和你断开连接了,这时候服务端就接收不到客户端的请求了,如果接收到了就表示没有真正断开连接。

四次挥手.png

示例小结

public class TCPTest {
    /**
     * 客户端
     */
    @Test
    public void client() throws IOException {
        Socket socket = null;
        OutputStream os = null;
        try {
            InetAddress inetAddress = 域名yName("127.0.0.1");
            //1创建Socke连接对象,指明要连接的服务端的ip和端口号
            socket = new Socket(inetAddress, 9000);
            //2获取输出流,用于输出数据
            os = 域名utputStream();
            //3写数据
            域名e("我叫客户端,你好啊".getBytes());
        } catch (IOException e) {
            域名tStackTrace();
        } finally {
            //4关闭流资源
            if (os != null) {
                域名e();
            }
            if (socket != null) {
                域名e();
            }
        }
    }

    @Test
    public void server() throws IOException {
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        ServerSocket serverSocket = null;
        Socket socket = null;
        try {
            //创建服务端的ServerSocket,指明自己的端口号,给客户端通过指定的ip和该端口号确定进程进行连接
            serverSocket = new ServerSocket(9000);
            //accept()用于接收来自客户端的连接
            socket = 域名pt();
            //获取输入流
            is = 域名nputStream();
            //读取输入流中的数据,ByteArrayOutputStream该流维护动态数组保存写入的数据
            baos = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int len;
            while ((len = 域名(buff)) != -1) {
                域名e(buff, 0, len);
            }
            域名tln(域名ring());
            域名tln("收到客户端请求了!");
        } catch (IOException e) {
            域名tStackTrace();
        } finally {
            //关闭资源
            域名e();
            域名e();
            域名e();
            域名e();
        }
    }
    /**
     * 我叫客户端,你好啊
     * 收到客户端请求了!
     */
}

示例小结——TCP发送接收文件

public class TCPFileTest {
    /**
     * 客户端给服务端发生文件
     */
    @Test
    public void client() throws IOException {
        Socket socket = null;
        OutputStream os = null;
        FileInputStream fis = null;
        ByteArrayOutputStream baos = null;
        try {
            InetAddress inetAddress = 域名yName("127.0.0.1");
            //1创建Socke连接对象,指明要连接的服务端的ip和端口号
            socket = new Socket(inetAddress, 9000);
            //2获取输出流,用于输出数据
            os = 域名utputStream();
            fis = new FileInputStream("是大臣.jpg");
            //3写数据
            byte[] buffer = new byte[1024];
            int len;
            while ((len = 域名(buffer)) != -1) {
                域名e(buffer, 0, len);
            }
            域名tln("向服务端发送图片成功!");
            //关闭数据的输出,不然服务端会一直阻塞着接收不往下走
            域名downOutput();
            //接收服务端的应答
            InputStream is = 域名nputStream();
            baos = new ByteArrayOutputStream();
            byte[] buff = new byte[1024];
            int length;
            while ((length = 域名(buff)) != -1) {
                域名e(buff, 0, length);
            }
            域名tln(域名ring());

        } catch (IOException e) {
            域名tStackTrace();
        } finally {
            //4关闭流资源
            if (os != null) {
                域名e();
            }
            if (socket != null) {
                域名e();
            }
        }
    }
    /**
     * 向服务端发送图片成功!
     * 客户端,你的文件收到了
     */

    /**
     * 服务端接收文件保存到本地
     *
     * @throws IOException
     */
    @Test
    public void server() throws IOException {
        InputStream is = null;
        FileOutputStream fos = null;
        ServerSocket serverSocket = null;
        Socket socket = null;
        OutputStream os = null;
        try {
            //创建服务端的ServerSocket,指明自己的端口号,给客户端通过指定的ip和该端口号确定进程进行连接
            serverSocket = new ServerSocket(9000);
            //accept()用于接收来自客户端的连接
            socket = 域名pt();
            //获取输入流
            is = 域名nputStream();
            //打开输出流写文件
            fos = new FileOutputStream("是大臣-域名");
            byte[] buff = new byte[1024];
            int len;
            while ((len = 域名(buff)) != -1) {
                域名e(buff, 0, len);
            }
            域名tln("收到客户端请求了!");
            //给客户端写出应答
            os = 域名utputStream();
            域名e("客户端,你的文件收到了".getBytes());
        } catch (IOException e) {
            域名tStackTrace();
        } finally {
            //关闭资源
            域名e();
            域名e();
            域名e();
            域名e();
            域名e();
        }
    }
    /**
     * 收到客户端请求了!
     */
}

UDP

域名
域名
域名
域名

示例小结

public class UDPTest {

    /**
     * 发生端
     */
    @Test
    public void sender() throws IOException {
        //1创建socket,发送端不需要指定要发生的ip和端口,直接在要发生的包里指定接收的地址端口即可。
        DatagramSocket socket = new DatagramSocket();
        byte[] data = "我是发送端,这是给你的一封信!".getBytes();
        //数据包要发送的地址
        InetAddress address = 域名yName("127.0.0.1");
        //2创建发送包
        DatagramPacket packet = new DatagramPacket(data, 0, 域名th, address, 9999);
        //3发送
        域名(packet);
        域名tln("发送数据成功!");
        //4关闭流
        域名e();
    }


    /**
     * 接收端
     */
    @Test
    public void receiver() throws IOException {
        //1创建接收端socket,要指定接收端的端口号,才能接收
        DatagramSocket socket = new DatagramSocket(9999);
        //2创建用于接收数据流的数组容器
        byte[] buffer = new byte[1024];
        //2创建接收包,用于接收数据包
        DatagramPacket packet = new DatagramPacket(buffer, 0, 域名th);
        //3发送
        域名ive(packet);
        //4打印接收到的数据
        域名tln(new String(域名ata(),0,域名ength()));
        域名tln("接收数据成功!");
        //5关闭流
        域名e();
    }
}

URL

域名
域名

示例小结

public class URLTest {

    /**
     * 使用url去下载网络文件
     *
     * @throws IOException
     */
    @Test
    public void urlTest() throws IOException {
        //URL相当于种子
        URL url = new URL("https://域名/feed/域名?token=dd219671927c0cb92aebbd8808110a70");
        //根据不同的协议强转不同的urlConnection,HttpsURLConnection或者HttpURLConnection
        HttpsURLConnection urlConnection = (HttpsURLConnection) 域名Connection();
        InputStream is = 域名nputStream();
        //写到本地
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("域名"));
        byte[] buff = new byte[1024];
        int len;
        while ((len = 域名(buff)) != -1) {
            域名e(buff, 0, len);
        }
        域名tln("下载成功了!");
        //关闭流
        域名e();
        域名e();
        域名onnect();
    }
}

参考

Java入门视频教程

618-630

标签:编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。