转一篇很全的关于Java Socket…
来源:互联网 发布:淘宝店铺排名怎么看 编辑:程序博客网 时间:2024/06/04 19:52
Java学习总结之第十六章 Socket用法详解
一、构造Socket
Socket的构造方法有以下几种重载形式:
(1)Socket()
(2)Socket(InetAddress address, int port)throwsUnknownHostException,IOException
(3)Socket(InetAddress address, int port, InetAddress localAddr, intlocalPort)throws IOException
(4)Socket(String host, int port) throwsUnknownHostException,IOException
(5)Socket(String host, int port, InetAddress localAddr, intlocalPort) throws IOException
各构造方法的用法如下:
1. 设定等待建立连接的超时时间:
Socket socket=new Socket();
SocketAddress remoteAddr=newInetSocketAddress("localhost",8000);
//等待建立连接的超时时间为1分钟
socket.connect(remoteAddr, 60000);
2. 设定服务器的地址:
Socket(InetAddress address, int port)
Socket(String host, int port)
InetAddress类表示IP地址,其用法如下:
//返回本地主机的IP地址
InetAddress addr1=InetAddress.getLocalHost();
//返回代表"222.34.5.7"的IP地址
InetAddress addr2=InetAddress.getByName("222.34.5.7");
//返回域名为"www.javathinker.org"的IP地址
InetAddress addr3=InetAddress.getByName("www.javathinker.org");
3. 设定客户端的地址:
在一个Socket对象中,既包含远程服务器的IP地址和端口信息,也包含本地客户端的IP地址和端口信息。默认情况下,客户端的IP地址来自于客户程序所在的主机,客户端的端口则由操作系统随机分配。Socket类还有两个构造方法允许显式的设置客户端的IP地址和端口:
Socket(InetAddress address, int port,
Socket(String host, int port,
4. 客户连接服务器时可能抛出的异常:
当Socket的构造方法请求连接服务器时,可能会抛出以下异常:
l UnknownHostException:如果无法识别主机的名字或IP地址,就会抛出这种异常。
l ConnectException:如果没有服务器进程监听指定的端口,或者服务器进程拒绝连接,就会抛出这种异常。
l SocketTimeoutException:如果等待连接超时,就会抛出这种异常。
l BindException:如果无法把Socket对象与指定的本地IP地址或端口绑定,就会抛出这种异常。
二、获取Socket的信息
以下方法用于获取Socket的有关信息:
l getInetAddress():获得远程服务器的IP地址。
l getPort():获得远程服务器的端口。
l getLocalAddress():获得客户本地的IP地址。
l getLocalPort():获得客户本地的端口。
lgetInputStream():获得输入流。如果Socket还没有连接,或者已经关闭,或者已经通过shutdownInput()方法关闭输入流,那么此方法会抛出IOException。
lgetOutputStream():获得输出流。如果Socket还没有连接,或者已经关闭,或者已经通过shutdownOutput()方法关闭输出流,那么此方法会抛出IOException。
三、关闭Socket
1.当客户与服务器的通信结束,应该及时关闭Socket,以释放Socket占用的包括端口在内的各种资源。Socket的close()方法负责关闭Socket。推荐代码如下:
Socket socket=null;
try{
socket=new
//执行接收和发送数据的操作
…
}catch(IOExceptione){
e.printStackTrace();
}finally{
try{
if(socket!=null)socket.close();
}catch(IOExceptione){e.printStackTrace();}
}
2. Socket类提供了三个状态测试方法:
l isClosed()
l isConnected()
l isBound()
3. 如果要判断一个Socket对象当前是否处于连接状态,可采用以下方式:
boolean isConnected=socket.isConnected() &&!socket.isClosed();
四、半关闭Socket
1. 有的时候,可能仅仅希望关闭输出流或输入流之一。此时可以采用Socket类提供的半关闭方法:
l shutdownInput():关闭输入流。
l shutdownOutput(): 关闭输出流。
2.先后调用Socket的shutdownInput()和shutdownOutput()方法,仅仅关闭了输入流和输出流,并不等价于调用Socket的close()方法。在通信结束后,仍然要调用Socket的close()方法,因为只有该方法才会释放Socket占用的资源,比如占用的本地端口等。
3. Socket类还提供了两个状态测试方法,用来判断输入流和输出流是否关闭:
l public boolean isInputShutdown()
l public boolean isOutputShutdown()
五、设置Socket的选项
Socket有以下几个选项:
n TCP_NODELAY:表示立即发送数据。
n SO_RESUSEADDR:表示是否允许重用Socket所绑定的本地地址。
n SO_TIMEOUT:表示接收数据时的等待超时时间。
n SO_LINGER:表示当执行Socket的close()方法时,是否立即关闭底层的Socket。
n SO_SNFBUF:表示发送数据的缓冲区的大小。
n SO_RCVBUF:表示接收数据的缓冲区的大小。
n SO_KEEPALIVE:表示对于长时间处于空闲状态的Socket,是否要自动把它关闭。
n OOBINLINE:表示是否支持发送一个字节的TCP紧急数据。
1. TCP_NODELAY选项
1) 设置该选项:public void setTcpNoDelay(boolean on) throwsSocketException
2) 读取该选项:public boolean getTcpNoDelay() throws SocketException
3)TCP_NODEALY的默认值为false,表示采用Negale算法。如果调用setTcpNoDelay(true)方法,就会关闭Socket的缓冲,确保数据及时发送:
if(!socket.getTcpNoDelay()) socket.setTcpNoDelay(true);
4)如果Socket的底层实现不支持TCP_NODELAY选项,那么getTcpNoDelay()和setTcpNoDelay()方法会抛出SocketException。
2. SO_RESUSEADDR选项
1) 设置该选项:public void setResuseAddress(boolean on) throwsSocketException
2) 读取该选项:public boolean getResuseAddress() throwsSocketException
3)为了确保一个进程关闭了Socket后,即使它还没释放端口,同一个主机上的其他进程还可以立刻重用该端口,可以调用Socket的setResuseAddress(true)方法:
if(!socket.getResuseAddress())socket.setResuseAddress(true);
4)值得注意的是socket.setResuseAddress(true)方法必须在Socket还没有绑定到一个本地端口之前调用,否则执行socket.setResuseAddress(true)方法无效。因此必须按照以下方式创建Socket对象,然后再连接远程服务器:
Socket socket =
socket.setResuseAddress(true);
SocketAddress remoteAddr =
socket.connect(remoteAddr);
或者:
Socket socket =
socket.setResuseAddress(true);
SocketAddress localAddr =
SocketAddress remoteAddr =
socket.bind(localAddr); //与本地端口绑定
socket.connect(remoteAddr);
3. SO_TIMEOUT选项
1) 设置该选项:public void setSoTimeout(int milliseconds) throwsSocketException
2) 读取该选项:public int getSoTimeOut() throws SocketException
3)当通过Socket的输入流读数据时,如果还没有数据,就会等待。Socket类的SO_TIMEOUT选项用于设定接收数据的等待超时时间,单位为毫秒,它的默认值为0,表示会无限等待,永远不会超时。
4)Socket的setSoTimeout()方法必须在接收数据之前执行才有效。此外,当输入流的read()方法抛出SocketTimeoutException后,Socket仍然是连接的,可以尝试再次读取数据。
4. SO_LINGER选项
1) 设置该选项:public void setSoLinger(boolean on, int seconds) throwsSocketException
2) 读取该选项:public int getSoLinger() throws SocketException
3) SO_LINGER选项用来控制Socket关闭时的行为。
lsocket.setSoLinger(true,0):执行Socket的close()方法时,该方法也会立即返回,但底层的Socket也会立即关闭,所有未发送完的剩余数据被丢弃。
lsocket.setSoLinger(true,3600):执行Socket的close()方法时,该方法不会立即返回,而进入阻塞状态,同时,底层的Socket会尝试发送剩余的数据。只有满足以下两个条件之一,close()方法才返回:
n 底层的Socket已经发送完所有的剩余数据。
n尽管底层的Socket还没有发送完所有的剩余数据,但已经阻塞了3600秒。close()方法的阻塞时间超过3600秒,也会返回,剩余未发送的数据被丢弃。
以上两种情况内,当close()方法返回后,底层的Socket会被关闭,断开连接。
4) setSoLinger(boolean on ,intsecond)方法中的seconds参数以秒为单位,而不是以毫秒为单位。
5. SO_RCVBUF选项
1) 设置该选项:public void setReceiveBufferSize(int size) throwsSocketException
2) 读取该选项:public int getReceiveBufferSize() throwsSocketException
3) SO_RCVBUF表示Socket的用于输入数据的缓冲区的大小。
4)如果底层Socket不支持SO_RCVBUF选项,那么setReceiveBufferSize()方法会抛出SocketException。
6. SO_SNDBUF选项
1) 设置该选项:public void setSendBufferSize(int size) throwsSocketException
2) 读取该选项:public int getSendBufferSize() throws SocketException
3) SO_SNDBUF表示Socket的用于输出数据的缓冲区的大小。
4)如果底层Socket不支持SO_SNDBUF选项,setSendBufferSize()方法会抛出SocketException。
7. SO_KEEPALIVE选项
1) 设置该选项:public void setKeepAlive(boolean on) throwsSocketException
2) 读取该选项:public int getKeepAlive() throws SocketException
3) 当SO_KEEPALIVE选项为true,表示底层的TCP实现会监视该连接是否有效。
4)SO_KEEPALIVE选项的默认值为false,表示TCP不会监视连接是否有效,不活动的客户端可能会永久存在下去,而不会注意到服务器已经崩溃。
8. OOBINLINE选项
1) 设置该选项:public void setOOBInline(int size) throwsSocketException
2) 读取该选项:public int getOOBInline () throws SocketException
3) 当OOBINLINE为true时,表示支持发送一个字节的TCP紧急数据。Socket类的sendUrgentDate(intdata)方法用于发送一个字节的TCP紧急数据。
4)OOBINLINE的默认值为false,在这种情况下,当接收方收到紧急数据时不作任何处理,直接将其丢弃。如果用户希望发送紧急数据,应该把OOBINLINE设为true:socket.setOOBInline(true);此时接收方会把接收到的紧急数据与普通数据放在同样的队列中。值得注意的是,除非使用一些更高层次的协议,否则接收方处理紧急数据的能力非常有限,当紧急数据到来时,接收方不会得到任何通知,因此接收方很难区分普通数据与紧急数据,只好按照同样的方式处理它们。
9. 服务类型选项
1) IP规定了四种服务类型,用来定性的描述服务的质量:
l 低成本:发送成本低。
l 高可靠性:保证把数据可靠的送达目的地。
l 最高吞吐量:一次可以接收或发送大批量的数据。
l 最小延迟:传输数据的速度快,把数据快速送达目的地。
2) 这四种服务类型还可以进行组合,例如,可以同时要求获得高可靠性和最小延迟。Socket类中提供了设置和读取服务类型的方法:
l 设置服务类型:public void setTrafficClass(int trafficClass) throwsSocketException
l 读取服务类型:public int getTrafficClass() throws SocketException
3) Socket类用四个整数表示服务类型:
l 低成本:0x02 (二进制的倒数第二位为1)
l 高可靠性:0x04(二进制的倒数第三位为1)
l 最高吞吐量:0x08(二进制的倒数第四位为1)
l 最小延迟:0x10(二进制的倒数第五位为1)
10. 设定连接时间、延迟和带宽的相对重要性
public void setPerformancePreference
以上方法的三个参数表示网络传输数据的三项指标:
n 参数connectionTime:表示用最少时间建立连接。
n 参数latency:表示最小延迟。
n 参数bandwidth:表示最高带宽。
setPerformancePreference
向文章作者
- 转一篇很全的关于Java Socket…
- 一篇关于程序员性格的文章 …
- 一篇关于程序员性格的文章(…
- 关于SVM一篇比较全介绍的博文(转)
- java socket编程【转】
- 关于Android Socket的总结
- 转一篇关于JAVA 断言的文章
- 基于JAVA socket的服务器客户…
- java socket的超时设置
- Java synchronized 关于…
- 【Java 易混点】 关于eq…
- 分享一篇关于C#对文件操作的日志,方法很全
- java socket编程
- java socket
- java socket学习
- java socket编程
- java socket
- 一篇关于RTP介绍比较全的文章
- js 小数取整的函数
- 转:串口通讯,关于javax.comm的安…
- 关于Java串口编程
- 关于Android Socket的总结
- ADB server didn't ACK
- 转一篇很全的关于Java Socket…
- 转:finally块中的代码一定会执行…
- 转:Android ANR异常及其解决方式
- 关于NDK-R7配置正确但是编译报awk&…
- 升级SDK和ADT
- Android Resource目录拾遗
- Finalement——Hello from&nbsp…
- 转:Android中Context详解
- Android.mk文件详解