1-21 计算机网络与Socket网络编程

本文详细介绍了TCP/IP通信的基础知识,包括IP地址、端口号、TCP/IP协议以及TCP的三次握手和四次挥手过程。此外,还探讨了socket套接字的概念和网络编程的基本步骤,展示了服务端和客户端的Java socket编程示例。重点讨论了TIME_WAIT状态的作用,确保可靠的数据传输。
摘要由CSDN通过智能技术生成
  1.  实现通信的条件
  1. IP地址

IP地址具有唯一性

IP地址的范围:0.0.0.0 - 255.255.255.255

本地IP地址:127.0.0.1 或 0.0.0.0

  1. IP协议

Internet Protocol 互联网协议,为计算机网络相互连接进行通信而设计的协议

  1. 端口号

端口号包括物理端口和逻辑端口

物理端口是用于连接物理设备之间的接口

逻辑端口是逻辑上用于区分服务的端口

端口号只有整数,范围从0-65535

1024-5000 分配给操作系统各个进程

大于5000为其他个人软件预留

常见开发软件的默认端口

HTTP

80

FTP

21

TELNET

23

tomcat

8080

MySQL

3306

2 TCP/IP协议

TCP协议Transmission Control Protocol 传输控制协议

IP协议Internet Protocol 互联网协议(网际互联协议)

通俗而言:TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。

  

3 TCP/IP五层模型-网络层次划分

  1. 应用层

网络服务与最终用户的一个接口

协议有:HTTP FTP SMTP TFTP SNMP DNS TELNET HTTPS POP3 DHCP

  1. 传输层

定义传输数据的协议端口号,以及流程控制和差错校验

协议有:TCP UDP

  1. 网络层

进行逻辑地址寻址,实现不同网络之间的路径选择

协议有:ICMP IGMP IP(IPv4 IPv6) ARP RARP

  1. 数据链路层

建立逻辑连接,进行硬件地址寻址,差错校验等功能

  1. 物理层

建立、维护、断开物理连接。(由底层网络定义协议 )

4 TCP建立连接-三次握手

TCP是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接

由于TCP是面向连接的所以只能用于端到端的通讯。TCP提供的是一种可靠的数据流服务,采用"带重传的肯定确认"技术来实现传输的可靠性。TCP还采用一种称为"滑动窗口"的方式进行流量控制,所谓窗口实际表示接收能力,用以限制发送方的发送速度。

 

字段

全称

名称

解释

seq

sequance

序列号

ack

acknowledge

确认号

SYN

synchronize

请求同步标志

请求建立连接,设置序列号为1

ACK

acknowledge

确认标志

确实是否有效,一般置为1

FIN

Finally

结束标志

 

TCP连接建立过程:

  1. 第一次握手请求建立连接客户端发送连接请求报文Client将标志位SYN置为1,随机为序列号产生一个值seq=x,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
  2. 第二次握手应答服务端接收连接请求后回复ACK确认报文,并为这次连接分配资源Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
  3. 第三次握手建立连接客户端接收到ACK报文后也向服务端ACK报文,并分配资源此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并将该数据包发送给ServerServer检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

5 TCP断开连接-四次挥手

 

  1. Client端发起中断连接请求,也就是发送FIN报文
  2. Serer端接收到FIN报文后,先发送ACK报文,确认接收到了Client端的请求,然后进入准备状态,此时Server端如果还有没发送完的数据,可以继续发送;
  3. Client端接收到Server端的ACK报文,进入FIN_WAIT状态,继续等待Server端的FIN报文
  4. 当Server端确定数据已发送完成,则向Client端发送FIN报文
  5. Client端接收到FIN报文后,再次发送ACK报文,然后进入TIME_WAIT状态,如果Server端没有接收到ACK报文可以重传;
  6. Server端收到ACK后,断开连接,Client端等待2MSL后依然没有收到回复,则证明Server端已正常关闭,Client端也可以关闭连接了。TCP连接就这样关闭了

问题:为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?

答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。

socket网络编程

6 socket套接字

IP地址+端口号组成了socket,socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础

网络上具有唯一标识的IP地址和端口号组合在一起,才能构成唯一能识别的标识符套接字.。

socket原理机制:

  1. 通信两端都有socket
  2. 网络通信其实就是socket之间的通信
  3. 数据在两个socket间通过IO流传输

7 socket编程实现即时通讯

服务端:

public class ServerNode {

public static void main(String[] args) throws IOException, InterruptedException {

        String readline = null;

        String inTemp = null;

        String turnLine = "\n";

        final String client = "Client:";

        final String server = "Server:";

        

        //端口号

        int port = 8081;

        //1 创建ServerSocket,监听端口8081

        ServerSocket serverSocket = new ServerSocket(port);  

        //2 调用服务器的accept方法,接受来自客户端的连接请求。接收到客户端连接请求之前,此方法会进行阻塞(程序会在这等待),当有申请连接时会建立连接并返回一个socket

        Socket socket = serverSocket.accept();

        //3 创建服务端输入流:获取系统输入的数据

        BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in));

        //4 创建客户端输入流:获取客户端传输的数据

        BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        //5 创建输出流:用于向客户端返回数据

        PrintWriter socketOut = new PrintWriter(socket.getOutputStream());

        

        while(readline != "bye"){//服务端系统输入bye时,终止连接

         //6 读取客户端输入流

            inTemp = socketIn.readLine();

            System.out.println(client + turnLine + inTemp);

            System.out.println(server);

            //7 服务端系统输入

            readline = systemIn.readLine();

            //8 向客户端返回数据

            socketOut.println(readline);

            /*

             * println() 和 write()的区别 

             * write方法只会写入字符,不会写入换行符和回车符

             * println方法意思是写入一行数据,会自带换行符

             *

             * 当readLine()方法只有读取到 \n 或者 \r 的时候,代表数据读取完毕

             * 否则会一直继续读取输入流的数据,直到有换行符出现

             * 如果用write方法,会造成程序执行阻塞

             */ 

            socketOut.flush(); //赶快刷新使Client收到,也可以换成socketOut.println(readline, ture)

        }

        systemIn.close();

        socketIn.close();

        socketOut.close();

        socket.close();

        serverSocket.close();

}

}

客户端

public class ClientNode {

public static void main(String[] args) throws IOException, InterruptedException {

String readline = null;

String inTemp = null;

String turnLine = "\n";

final String client = "Client:";

final String server = "Server:";

//服务端端口号

int port = 8081;

/*

 * 服务端ip地址

 */

// byte ipAddressTemp[] = {127, 0, 0, 1};

// InetAddress ipAddress = InetAddress.getByAddress(ipAddressTemp);

//首先直接创建socket,端口号1~1023为系统保存,一般设在1023之外

Socket socket = new Socket("127.0.0.1", port);

BufferedReader systemIn = new BufferedReader(new InputStreamReader(System.in));

BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));

PrintWriter socketOut = new PrintWriter(socket.getOutputStream());

    while(readline != "bye"){

//客户端:读取系统字节流

System.out.println(client);

readline = systemIn.readLine();

//客户端:输出流向服务端发送数据

socketOut.println(readline);

socketOut.flush(); //赶快刷新使Server收到,也可以换成socketOut.println(readline, ture)

//读取服务端返回的数据

inTemp = socketIn.readLine();

System.out.println(server + turnLine + inTemp);

    }

    //关闭资源

        systemIn.close();

        socketIn.close();

        socketOut.close();

        socket.close();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值