欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

浅谈网络编程之Socket

程序员文章站 2022-05-06 16:51:18
...

前言

此文只是简单概述Socket,Java编程的使用方法,还请移步Java 网络IO编程

Socket

Socket是用来连接网路,进行传输数据的工具,Scoket大致分为两种,TCP和UDP
TCP:
服务端:创建Socket->绑定ip和端口号->接听连接->accept连接
客户端:创建Socket->connect服务器

在创建Socket的时候其实并不区分客户端还是服务器端,如果绑定ip、端口则为服务端Socket,调用connect则为客户端Socket

Java 网络IO编程的Socket使用解读

在Java网络IO编程中,当我们创建一个服务端ServerSocket实例,例如

ServerSocket serverSocket = new ServerSocket(8000);

好像我们并没有绑定ip?

当我们进入源码,就会发现,当ip不传的时候,它在构造时默认为我们绑定了一个地址——“0.0.0.0”。0.0.0.0代表的是本机所有ip地址,也就是说我们的Socket接收任意来自本机ip的连接,如果构造时传了ip地址,那么接收来自固定ip地址的连接。

我们再来看下客户端

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

好像不仅没有调用connect,还绑定了ip,端口。

我们再次进入源码,就能发现,我们传进去的ip和端口是用来建立连接的。源码就不贴了,大家有兴趣可以看下,都很好理解。

当完成消息传输后,服务端和客户端都会停止运行。

有些小伙伴可能会觉得,在Java里我明明用的是不同的“Socket”,比如serverSocket类,Socket类。还请注意,本文中的Socket表示的是“套接字”这个概念,而并非某个具体的实现类。其实到源码里会发现,Java代码的实际逻辑实现都用到了SocketOptions接口的实现类。

 

Socket的传输方式与协议

  • 面向连接的数据传输方式:
    保证在传输的过程中数据不会消失、按序传递数据,并且数据的传输是没有边界的(比如在Socket编程时,TCP包头中没有“包长度字段”)。如果接收端读取数据的速度慢于传输端,导致接收端无法再接收,那么传输端会停止传输。如果传输出错还提供重传服务
    使用此数据传输方式的协议:TCP

  • 面向消息的数据传输方式:
    不存在连接的概念
    不可靠的,不按序传递,以数据高速传递为目的,且每次传递的数据大小有限制
    使用此数据传输方式的协议:UDP

同一协议族中可能存在多个数据传输方式相同的协议。

Socket使用的时候需要指定协议,在Java编程中,我们构造Socket时似乎并没有指定使用的协议。但其实当我们使用Socket类、serverSocket类的时候,内部使用的是TCP协议的实现类;使用DatagramSocket类,MulticastSocket类时,内部使用的是UDP协议的实现类。有兴趣可以研究一下SocketImpl 和DatagramSocketImpl

扩展
我们平时说的TCP,UDP都属于TCP/IP协议族,TCP/IP协议并不完全符合OSI的七层参考模型,而是由四个层次组成:链路层、网络(IP)层、传输层、应用层。我们的TCP,UDP位于传输层。

两台主机想要通过网络进行数据交换,需要先建立两台主机的物理连接(链路层负责)

为了在复杂的网络中传输数据,需要考虑向目标传输数据需要经过哪条路径(IP层负责)

IP层解决路径问题后,我们只要按照此路径传输数据即可,传输层以IP层提供的路径信息为基础完成实际的数据传输。

我们需要根据程序的特点决定服务器与客户端之间的数据传输规则,这就是应用层协议,网络编程大部分内容就是设计实现应用层协议。

向我们提供的工具便是Socket,以上内容都是Socket通信过程中自动处理的。选择数据传输路径,数据确认,数据传输过程都被隐藏到Socket内部。我们只需要利用Socket编写出程序即可。

分配给套接字的IP地址和端口号

大家还记得在创建服务端Socket的时候,我们需要绑定端口和ip,我们的端口号并非赋予计算机的值,而是为了区分程序中创建的Socket而分配给Socket的序号。初始化服务端Socket时应分配所属计算机的IP地址,同一个计算机可以分配多个IP地址,所以我们需要指定接收哪个IP传来的数据。如上文所述,如果为0.0.0.0,则接收来自该计算机所有ip的连接。

后记

创建一个Socket需要指定协议,ip,端口(不管是用来bind还是connect),创建的套接字时,TCP,UDP协议可以使用同样的端口号,因为他们的协议是不一样的。

 

参考书籍:《TCP/IP网络编程》(韩)尹圣雨