Socket协议简介
标签(空格分隔): tcp ip udp socket
学习java tcp/ip socket编程
- 编写 TCP 客户端程序,在实例化 Socket 类时,要注意,底层的 TCP 协议只能处理 IP 协议,如果传递的第一个参数是主机名字而不是你 IP 地址,Socket 类具体实现的时候会将其解析成相应的地址,若因为某些原因连接失败,构造函数会抛出一个 IOException 异常。
- TCP 协议读写数据时,read()方法在没有可读数据时会阻塞等待,直到有新的数据可读。另外,TCP 协议并不能确定在 read()和 write()方法中所发送信息的界限,接收或发送的数据可能被 TCP 协议分割成了多个部分。
- 编写 TCP 服务器端的程序将在 accept()方法处阻塞,以等待客户端的连接请求,一旦取得连接,便要为每个客户端的连接建立一个 Socket 实例来进行数据通信。
- 在 UDP 程序中,创建 DatagramPacket 实例时,如果没有指定远程主机地址和端口,则该实例用来接收数据(尽管可以调用 setXXX()等方法指定),如果指定了远程主机地址和端口,则该实例用来发送数据。
- UDP 程序在 receive()方法处阻塞,直到收到一个数据报文或等待超时。由于 UDP 协议是不可靠协议,如果数据报在传输过程中发生丢失,那么程序将会一直阻塞在 receive()方法处,这对客户端来说是肯定不行的,为了避免这个问题,我们在客户端使用 DatagramSocket 类的 setSoTimeout()方法来制定 receive()方法的最长阻塞时间,并指定重发数据报的次数,如果每次阻塞都超时,并且重发次数达到了设置的上限,则关闭客户端。
- UDP 服务器为所有通信使用同一套接字,这点与 TCP 服务器不同,TCP 服务器则为每个成功返回的 accept()方法创建一个新的套接字。
- 在 UDP 程序中,DatagramSocket 的每一次 receive()调用最多只能接收调用一次 send()方法所发送的数据,而且,不同的 receive()方法调用绝对不会返回同一个 send()方法所发送的额数据。
- 在 UDP 套接字编程中,如果 receive()方法在一个缓冲区大小为 n 的 DatagramPscket 实例中调用,而接受队列中的第一个消息长度大于 n,则 receive()方法只返回这条消息的前 n 个字节,超出的其他字节部分将自动被丢弃,而且也没有任何消息丢失的提示。因此,接受者应该提供一个足够大的缓存空间的 DatagramPacket 实例,以完整地存放调用 receive() 方法时应用程序协议所允许的最大长度的消息。一个 DatagramPacket 实例中所运行传输的最大数据量为 65507 个字节,即 UDP 数据报文所能负载的最多数据,因此,使用一个有 65600 字节左右缓存数组的数据总是安全的。
- 在 UDP 套接字编程中,每一个 DatagramPacket 实例都包含一个内部消息长度值,而该实例一接收到新消息,这个长度值便可能改变(以反映实际接收的消息的字节数)。如果一个应用程序使用同一个 DatagramPacket 实例多次调用 receive()方法,每次调用前就必须显式地将消息的内部长度重置为缓冲区的实际长度。
- 另一个潜在问题的根源是 DatagramPacket 类的 getData()方法,该方法总是返回缓冲区的原始大小,忽略了实际数据的内部偏移量和长度信息。
- 具体的细节可以去下载 java tcp/ip socket编程这本书