浅谈网络编程之Socket
前言
此文只是简单概述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网络编程》(韩)尹圣雨
上一篇: Java 面试题及其答案
下一篇: gc参数设置错误导致一直full gc