Java网络编程学习笔记(五)客户端Socket
来源:互联网 发布:php array splice 编辑:程序博客网 时间:2024/05/22 14:13
使用Socket
Socket是两台主机之间的一个连接。它可以完成7个基本操作:
- 连接远程机器。
- 发送数据。
- 接受数据。
- 关闭连接。
- 绑定端口。
- 监听入站数据。
- 在绑定端口上接受来自远程机器的连接。
Java的Socket类(客户端和服务端都可以使用)提供了前4个操作的方法。后面3个操作仅服务器需要,即等待客户端的连接,这些操作由ServerSocket类实现。
构造和连接Socket
java.net.Socket类是Java完成客户端TCP操作的基础类。其他建立TCP网络连接的面向客户端的类(如URL、URLConnection、Applet和JEditorPane)最终都会调用这个类的方法。
设置超时时间
强烈推荐使用setSoTimeOut()方法为连接设置一个超时时间。超时时间按毫秒度量,所以下面这个语句设置socket在15秒无响应之后超时:
socket.setSoTimeOut(15000);
对于一个本地内部网服务器来说,15秒的响应时间太长了,但是对于一个负载很大的公共服务器(如time.nist.gov),这个时间则很短。一旦打开socket并设置其超时时间,可以调用getInputStream() 来返回一个InputStream,用它从socket读取字节。
基本构造函数
每个Socket构造函数指定要连接的主机和端口。主机可以指定为InetAddress或String。远程端口指定为1到65535之间的int值:
public Socket(String host, int port) throws UnknownHostException, IOExceptionpublic Socket(InetAddress host, int port) throws IOException
这些构造函数会连接socket,即在构造函数返回之前,会与远程主机建立一个活动的网络连接。
选择从哪个本地接口连接
有两个Socket构造函数可以指定要连接的主机和端口,以及从哪个接口和端口连接:
public Socket(String host, int port, InetAddress interface, int localPort) throws IOException, UnknownHostExceptionpublic Socket(InetAddress host, int port, InetAddress interface, int localPort) throws IOException
这个Socket连接到前两个参数中指定的主机和端口。它从后两个参数指定的本地网络接口和端口来连接。
构造但不连接
如果没有为Socket构造函数提供任何参数,它就没有目标主机可以连接:
public Socket()
可以以后再为某个connect()方法传入一个SocketAddress来建立连接。
Socket地址
SocketAddress类(一个空的抽象类)表示一个连接端点。当前只支持TCP/IP Socket。实际使用的Socket地址都是InetSocketAddress的实例。SocketAddress类的主要用途是为暂时的socket连接信息(如IP地址和端口)提供一个方便的储存。Socket类提供了两个返回SocketAddress对象的方法:
public SocketAddress getRemoteSocketAddress()public SocketAddress getLocalSocketAddress()
getRemoteSocketAddress()返回所连接系统的地址,getLocalSocketAddress()返回发起连接的地址,如果Socket尚未连接,则这两个方法都返回null。通常会用一个主机和一个端口(对于客户端)或者只使用一个端口(对于服务器)来创建InetSocketAddress类(SocketAddress唯一的子类):
public InetSocketAddress(InetAddress address, int port)public InetSocketAddress(String host, int port)public InetSocketAddress(int port)
还可以使用该静态工厂类方法从而不再在DNS中查找主机:
public static InetSocketAddress createUnresolved(String host, int port)
InetSocketAddress提供了一些获取方法,可以用来检查这个对象:
public final InetAddress getAddress()public final int getPort()public final String getHostName()
代理服务器
最后一个构造函数创建一个未连接的Socket,它通过一个指定的代理的服务器连接:
public Socket(Proxy proxy)
一般情况下,Socket使用的代理服务器由socksProxyHost和socksProxyPort系统属性控制,这些属性应用于系统中的所有Socket。但是构造函数创建的socket会使用指定的代理服务器。最值得一提的是,可以为参数传入Proxy.NO_PROXY,完全绕过所有代理服务器,而直接连接远程主机。
获取Socket的信息
Socket对象有一些属性可以通过获取方法来访问:
public InetAddress getInetAddress() // 访问远程地址public int getPort() // 访问远程端口public InetAddress getLocalAddress() // 访问本地地址public int getLocalPort() // 访问本地端口
如果连接现在是关闭的,getInetAddress()和getPort()方法则给出Socket连接时所连接的主机和端口。
关闭还是连接
isClosed()
如果socket关闭,该方法会返回true。不过,这不是一个万全的测试。如果Socket从一开始从未连接,该方法也会返回false。isConnected()
该方法会指出Socket是否从未连接过一个远程主机。要查看一个Socket当前是否打开,需要检查两个条件,首先isConnected()要返回true,另外isClosed()要返回false。isBound()
该方法会告诉你Socket是否成功地绑定到本地系统上的出站端口。
toString()
Socket类只覆盖了java.lang.Object中的一个标准方法:toString()。toString()方法会生成一个类似这样的字符串:
Socket[addr=www.oreilly.com/198.112.208.11,port=80,localport=50055]
该方法主要用于调试,不过不要依赖这个格式,将来格式可能会改变。
设置Socket选项
- TCP_NODELAY
public void setTcpNoDelay(boolean on) throws SocketExceptionpublic boolean getTcpNoDelay() throws SocketException
设置TCP_NODELAY为true可确保包会尽快地发送,而无论包的大小。如果远程系统没有足够快地将确认发送回本地系统,那么依赖于小数据量信息稳定传输的应用程序会变得很慢。因此,这个选项在游戏或网络计算机应用程序(服务器需要实时跟踪客户端鼠标的移动)中很重要。
- SO_LINGER
public void setSoLinger(boolean on, int seconds) throws SocketExceptionpublic int getSoLinger() throws SocketException
SO_LINGER选项指定了Socket关闭时如何处理尚未发送的数据报。默认情况下,close()方法将其立即返回,但系统仍会尝试发送剩余的数据。如果SO_LINGER打开而且延时设置为任意正数,close()方法会阻塞,等待发送数据和接收确认。
- SO_TIMEOUT
public void setSoTimeOut(int millisceonds) throws SocketExceptionpublic int getSoTimeOut() throws SocketException
正常情况下,尝试从Socket读取数据时,read()调用会阻塞尽可能长的时间来得到足够的字节。设置SO_TIMEOUT可以确保这次调用阻塞的时间不会超过某个固定的毫秒数。当时间到期时就会抛出一个InterruptedIOException异常,你应当准备好捕获这个异常。不过,Socket仍然是连接的,下一次调用可能会成功。超时时间按毫秒给出,0被解释为无限超时,这是默认值。
- SO_RCVBUF和SO_SNDBUF
TCP使用缓冲区提升网络性能。较大的缓冲区会提升快速连接的性能,而较慢的连接利用较小的缓冲区会有更好的表现。
public void setReceiveBufferSize(int size) throws SocketException, IllegalArgumentExceptionpublic int getReceiveBufferSize() throws SocketExceptionpublic void setSendBufferSize(int size) throws SocketException, IllegalArgumentExceptionpublic int getSendBufferSize() throws SocketException
尽管看起来应该能独立地设置发送和接收缓冲区,但实际上缓冲区通常会设置为二者中较小的一个。不过,底层实现完全可以忽略或调整这个建议。不过,大多数情况下,除非网络在某个方向上负载过大,否则默认值就很合适。
- SO_KEEPALIVE
public void setKeepAlive(boolean on) throws SocketExceptionpublic boolean getKeepAlive() throws SocketException
如果打开了SO_KEEPALIVE,客户端偶尔会通过一个空闲连接发送一个数据包(一般两小时一次),以确保服务器未崩溃。
- OOBINLINE
下面的这个方法几乎会立即发送参数中的最低字节。
public void sendUrgentData(int data) throws IOException
默认情况下,Java会忽略从Socket接收的紧急数据。不过,如果你希望接收正常数据中的紧急数据,就需要使用下面的方法设置OOBINLINE选项为true:
public void setOOBInline(boolean on) throws SocketExceptionpublic boolean getOOBInline() throws SocketException
Java不区分紧急数据和非紧急数据,这使它不能理想地发挥作用,不过如果有一个特定字节对你的程序有特殊含义,而且从不出现在常规的输入流中,这就能让你更快地发送这个字节。
- SO_REUSEADDR
如果开启SO_REUSEADDR(默认为关闭),就允许另一个Socket绑定到一个刚刚关闭但未释放的端口,即使此时仍有可能存在前一个Socket未接收的数据。
public void setReuseAddress(boolean on) throws SocketExceptionpublic boolean getReuseAddress() throws SocketException
- IP_TOS服务类型
服务器类型储存在IP首部中一个名为IP_TOS的8位字段中。Java允许你使用下面两个方法检查和设置Socket放在这个字段中的值:
public int getTrafficClass() throws SocketExceptionpublic void setTrafficClass(int trafficClass) throws SocketException
在21世纪的TCP栈中,这个字节的高6位包含一个差分服务代码点(Differentiated Services Code Point, DSCP)值,低两位包含一个显式拥塞通知(Explicit Congestion Notification,ECN)值。作为表达偏好的另一种方法,setPerformancePreferences()方法为连接时间、延迟和带宽指定相对优先性。
- Java网络编程学习笔记(五)客户端Socket
- python 网络编程基础学习笔记(1)-网络客户端-socket
- Unix网络编程学习日记(五):基于epoll与管道的socket客户端
- java学习笔记------java网络编程五
- Java网络编程 客户端Socket
- Java学习笔记--网络编程Socket
- 【Java学习笔记】23.网络编程--Socket
- Java Socket网络编程五
- JAVA学习笔记(网络编程 之 socket)
- Java网络编程学习笔记(六)服务器Socket
- java学习笔记(五)——网络编程
- java网络socket编程(二)之Socket客户端
- 网络编程学习笔记(一)-----socket
- Socket网络编程学习笔记(转)
- 网络编程 笔记(五) 回声服务器/客户端
- Socket网络编程学习笔记
- Socket网络编程学习笔记
- Socket网络编程学习笔记
- 第16课:Scala implicits编程彻底实战及Spark源码鉴赏
- Serverless
- c++中输入输出流的格式控制符:
- perl路经详解
- 使用汇编语言实现if else 循环 函数调用
- Java网络编程学习笔记(五)客户端Socket
- 文章标题
- c++笔记
- elasticsearch2.1部署
- c++格式说明符
- HDFS Federation机制
- poj 3253 优先队列 堆
- C++:string 的substr()和assign()
- C#控制台基础 打开指定的文件夹后,第一眼看到的文件夹的名字,创建日期,最后修改日期