首页 > 编程语言 >7.Java 网络编程之 Socket

7.Java 网络编程之 Socket

时间:2023-04-19 10:34:51浏览次数:42  
标签:Java Socket ACK IP 编程 SYN 服务器 连接 客户端

Java 网络编程之 Socket

一、课程目标

网络模型
TCP 协议与 UDP 协议区别
Http 协议底层实现原理。

二、什么是网络模型

网络编程的本质是两个设备之间的数据交换,当然,在计算机网络 中,设备主要指计算
机。数据传递本身没有多大的难度,不就是把一个设备中的数据发送给两外一个设备,然
后接受另外一个设备反馈的数据。
现在的网络编程基本上都是基于请求/ / 响应方式的,也就是一个设备发送请求数据给
另外一个,然后接收另一个设备的反馈。
在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端
(Client) ,等待 其他程序连接的程序被称作服务器 (Server) 。客户端程序可以在需要的时
候启动,而服务器为了能够时刻相应连接,则需要一直启动。例如以打电话为例,首先拨
号的人类似于客户端,接听电话的人必须保持电话畅通类似于服务器。
连接一旦建立以后,就客户端和服务器端就可以进行数据传递了,而且两者的身份是
等价的。
在一些程序中,程序既有客户端功能也有服务器端功能,最常见的软件就是 BT 、
e emule 这类软件了。
下面来谈一下如何建立连接以及如何发送数据。

2. 1 、IP地址与域名

在现实生活中,如果要打电话则需要知道对应人的电话号码,如果要寄信则需要知道收信
人的地址。在网络中也是这样,需要知道一个设备的位置,则需要使用该设备的 IP 地
址,具体的连接过程由硬件实现,程序员不需要过多的关心。
IP 地址是一个规定,现在使用的是 IPv4 ,既由 4 个 0- - 255 之间的数字组成,在计算
机内部存储时只需要 4 个字节即可。在计算机中, IP 地址是分配给网卡的,每个网卡有一
个唯一的 IP 地址,如果一个计算机有多个网卡,则该台计算机则拥有多个不同的  IP 地
址,在同一个网络内部, IP 地址不能相同。 IP 地址的概念类似 于电话号码、身份证这样
的概念。
由于 IP 地址不方便记忆,所以有专门创造了域名 (Domain Name) 的概念,其实就是给
IP 取一个字符的名字,例如 163.com 、m sina.com 等。IP 和域名之间存在一定的对应关
系。如果把 P IP 地址类比成身份证号的话,那么域名就是你的姓名。
其实在网络中只能使用 IP 地址进行数据传输,所以在传输以前,需要把域名转换为
IP ,这个由称作 DNS 的服务器专门来完成。
所以在网络编程中,可以使用 IP 或域名来标识网络上的一台设备。

2.2、端口的概念

为了在一台设备上可以运行多个程序,人为的设计了端口 (Port) 的概念,类似的例子是公
司内部的分机号码。
规定一个设备有 216 个,也就是 65536 个端口,每个端口对应一个唯一的程序。每个
网络程序,无论是客户端还是服务器端,都对应一个或多个特定的端口号。由于  0- - 1024
之间多被操作系统 占用,所以实际编程时一般采用 1024 以后的端口号。
使用端 口号,可以找到一台设备上唯一的一个程序。
所以如果需要和某台计算机建立连接的话,只需要知道  IP 地址或域名即可,但是如
果想和该台计算机上的某个程序交换数据的话,还必须知道该程序使用的端口号。
小结
网络编程就是使用  IP 地址,或域名,和端口连接到另一台计算机上对应的程序,按照
规定的协议( ( 数据格式) ) 来交换数据,实际编程中建立连接和发送、接收数据在语言级已经
实现,做的更多的工作是设计协议,以及编写生成和解析数据的代码罢了,然后把数据转
换成逻辑的结构显示或控制逻辑即可。
对于初学者,或者没有接触过网络编程的程序员,会觉得网络编程涉及的知识很高深,
很难,其实这是一种误解,当你的语法熟悉以后,其实基本的网络编程现在已经被实现的
异常简单了。

三、网络模型图

四、 Socket 入门

4.1、什么是Socket?

Socket 就是为网络服务提供的一种机制。
通讯的两端都有 Sokcet
网络通讯其实就是  Sokcet 间的通讯
数据在两个  Sokcet 间通过 IO 传输。

4.2、TCP与UDP在概念上的区别:

udp:
a  、是面向无连接 , 将数据及源的封装成数据包中 , 不需要建立建立连接
b  、每个数据报的大小在限制  64k 内
c  、因无连接, ,是不可靠协议
d  、不需要建立连接 , 速度快
tcp : 
a  、建议连接,形成传输数据的通道 .
b  、在连接中进行大数据量传输,以字节流方式
c  、通过三次握手完成连接 , 是可靠协议
d  、必须建立连接  m 效率会稍低

4.3 、 UDP 协议

通过 UDP 协议

4.3.1.UDP服务器端代码

class UdpServer {
    public static void main(String[] args) throws IOException {
        System.out.println("udp 接受数据启动.......");
        DatagramSocket ds = new DatagramSocket(8080);
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf, buf.length);
        // 阻塞效果
        ds.receive(dp);
        System.out.println(" 来源: "+dp.getAddress().getHostAddress()+", port: "+dp.getPort());
            String str = new String(dp.getData(), 0, dp.getLength()); System.out.println(" 客户端发送数据:" + str); ds.close();
        }
    }

4.3.2 UDP客户端代码

public class UdpClient {
    public static void main(String[] args) throws IOException {
        System.out.println("udp 发送数据");
        DatagramSocket ds = new DatagramSocket();
        String str = " 客户端发送数据....";
        byte[] strByte = str.getBytes();
        DatagramPacket dp = new DatagramPacket(strByte, strByte.length,
            InetAddress.getByName("192.168.1.3"), 8080);
        ds.send(dp);
        ds.close();
    }
}

4.3 .TCP 协议

4.3.3 TCP握手协议

在 P TCP/IP 协议中,P TCP 协议采用三次握手建立一个连接。
第一次握手: : 建立连接时,客户端发送 N SYN 包 (SYN=J) 到服务器,并进入 D SYN_SEND 状态,等
待服务器确认;
第二次握手: : 服务器收到 N SYN 包,必须确认客户的 N SYN ( ACK=J+1 ),同时自己也发送一个 SYN
包( SYN=K ),即 K SYN+ACK 包,此时服务器 V V 状态;
第三次握手: : 客户端收到服务器的 SYN +K ACK 包,向服务器发送确认包 ACK(ACK=K+1) ,此包
发送完毕,客户端和服务器进入 D ESTABLISHED 状态,完成三次握手。
完成三次握手 ,客户端与服务器开始传送数据,

四次分手:
于 由于TCP 连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它
的数据发送任务后就能发送一个 FIN 来终止这个方向的连接。收到一个 FIN 只意味着这一
方向上没有数据流动,一个TCP 连接在收到一个 FIN 后仍能发送数据。首先进行关闭的一
方将执行主动关闭,而另一方执行被动关闭。
(1 )客户端 A 发送一个 FIN ,用来关闭客户 A 到服务器 B 的数据传送。
(2 )服务器 B 收到这个 FIN ,它发回一个 ACK ,确认序号为收到的序号加 1 。和 SYN 一样,
一个 N FIN 将占用一 个序号。
(3 )服务器 B 关闭与客户端 A 的连接,发送一个FIN 给客户端 A  。
(4 )客户端 A 发回 ACK 报文确认,并将确认序号设置为收到序号加 1 。

1. 为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?
这是因为服务端的 LISTEN 状态下的  SOCKET 当收到  SYN 报文的建连请求后,它可以
把  ACK 和 SYN ( ACK 起应答作用,而  SYN 起同步作用)放在 一个报文里来发送。
但关闭连接时,当收到对方的  FIN 报文通知时,它仅仅表示对方没有数据发送给你了;但未
必你所有的数据都全部发送给对方了,所以你可以 未 必会马上会关闭 SOCKET, 也即你可能
送 还需要发送一些数据给对方之后,再发送 FIN 报文给对方来表示你同意现在可以关闭连接
了,所以它这里的  ACK 报 文和  FIN 报文多数情况下都是分开发送的. .
 2 .为什么  TIME_WAIT 状态还需要等  2MSL 后才能返回到  CLOSED 状态?
的 这是因为虽然双方都同意关闭连接了,而且握手的  4 个报文也都协调和发送完毕,按理可
以直接回到  CLOSED 状态(就好比从 SYN_SEND 状态到  ESTABLISH 状态那样);但是因为我们
的 必须要假想网络是不可靠的,你无法保证你最后发送的  ACK 报文会一定被对 方收到,因此
对方处于  LAST_ACK 状态下的  SOCKET 可能会因为超时未收到  ACK 报文,而重发  FIN 报文,
所以这个  TIME_WAIT 状态的作用就是用来重发可能丢失的  ACK 报文。

4.3.1 服务器端代码

public class TcpServer {
    public static void main(String[] args) throws IOException {
        System.out.println("socket 服务器端启动....");
        ServerSocket serverSocket = new ServerSocket(8080);
        // 获取客户端对象
        Socket accept = serverSocket.accept();
        InputStream inputStream = accept.getInputStream();
        byte[] buf = new byte[1024];
        int len = inputStream.read(buf);
        String str = new String(buf, 0, len);
        System.out.println("str:" + str);
        serverSocket.close();
    }
}

4.3.2 客户端代码

System.out.println("socket 启动 ....");
Socket s = new Socket("192.168.1.3", 8080);
OutputStream outputStream = s.getOutputStream();
outputStream.write("我是客戶端 ....".getBytes());
s.close();

标签:Java,Socket,ACK,IP,编程,SYN,服务器,连接,客户端
From: https://www.cnblogs.com/salixleaf/p/17141245.html

相关文章

  • 14.SpringAOP 编程
    SpringAOP编程课程目标代理设计模式Spring的环境搭建SpringIOC与AOPSpring事物与传播行为一、代理模式1.1概述代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理访问目标对象。这样好处:可以在目标对象实现的基础上,增强额外的功能操作。(扩......
  • Socket是什么/怎么理解Socket
    Socket先来看一下百度百科对于Socket的介绍:套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。我们将一个小......
  • [nacos]JAR启动并加载/解析Nacos yml格式的配置文件时,报“java.nio.charset.Malformed
    1问题描述原因1:字符集不匹配nacos中配置文件的字符集为A,应用程序的读取配置文件时使用了字符集B,导致使用字符集B解码文件二进制流时字符解码失败。一般问题出在中文注释上原因2:(yml文件)配置格式有误2解决思路2.1原因1:字符集不匹配时方法[1]删除nacos配置文件中......
  • java基础数据类型
    这里整理java基础数据类型学习时几个需要注意的地方,防止自己使用错误,走错路...整数//整数intnum1=10;bytenum2=20;shortnum3=30;longnum4=30L;//long类型要在数字后面加个L//整数拓展进制:二进制0b十进制八进......
  • 每日编程一小时(第十天)
    一.问题描述5本新书借给3人,没人最多借一本,有多少种借法二.设计思路1.采用枚举的方法列出所有的选择情况2.利用判定条件删去不符合条件的情况,剩下的全部为符合条件的情况三.流程图 四.代码实现#include<iostream>usingnamespacestd;intmain(){intA,B,C,fl......
  • Java的对象克隆
    本节我们会讨论Cloneable接口,这个接口指示一个类提供了一个安全的clone()方法。Object类提供的clone()方法是“浅拷贝”,并没有克隆对象中引用的其他对象,原对象和克隆的对象仍然会共享一些信息。深拷贝指的是:在对象中存在其他对象的引用的情况下,会同时克隆对象中引用的其......
  • Java-Day-12( 类变量 + 类方法 + main 方法 + 代码块 + 单例设计模式 + final 关键字 )
    Java-Day-12类变量定义一个变量count,是一个类变量(静态变量)staticclassPerson{privateStringname;// 该静态变量static最大的特点就是会被Person所有的对象实例共享publicstaticintcount=0;publicPerson(Stringname){this.na......
  • 变编程一小时2023.4.18
    1.#include<iostream>usingnamespacestd;classShape{ public: virtualdoublearea()const=0;};classCircle:publicShape{ public: Circle(doubler):radius(r) { } virtualdoublearea()const { return3.14159*radius*radius; } protected: dou......
  • 每日八股文之Java
    1、请你说说多线程得分点:线程和进程的关系、为什么使用多线程进程是操作系统资源调度的基本单位,线程是处理器任务调度和执行的基本单位,一个进程可以创建多个线程,每个线程有自己独立的程序计数器,本地方法栈和虚拟机栈,线程之间共享进程的堆和方法区。线程之间是通过时间片算法......
  • Java包
    包包是一组类和接口的集合。包的引入,实现了封装特性。同一个包中不允许有同名的类和接口,不同的包中允许同名的类和接口。包的引入,解决了类名的冲突问题。包本身也是分级的,包中还可以有子包。Java的包可以用文件系统来存放,也可以存放在数据库中。在Windows中,包是以文件系统来......