java网络编程学习(三)

主题:Socket


一 使用Socket


1 Socket是两台主机之间的一个连接,它可以完成7个基本操作:

(1) 连接远程机器

(2) 发送数据

(3) 接收数据

(4) 关闭连接

(5) 绑定端口

(6) 监听入站数据

(7) 在绑定的端口上接收来自远程机器的连接


2 Java中的Socket连接基于C-S模式,客户端Socket使用Java提供的Socket类,完成前4个操作;服务端Socket使用Java提供的ServerSocket类,完成后3个操作。


3 使用客户端socket的一般方式


Socket socket = null;

try{

socket = new Socket("hostname", 13);

}catch(IOException e){

e.printTrace();

}finnaly{

if(socket!= null){

try{

socket.close()

}catch(Exception e){}

}

}



try(Socket socket = new Socket("hostname", 13)){

//do something

}catch(Exception e){

}


二 构造Socket

1 基本构造函数(目标端口范围1-65535,本地端口范围会随机选择1024-65535)

public Socket(String host, int port) throws UnknowHostException, IOException

public Socket(InetAddress host, int port) throws  IOException


2 选择从哪个本地接口连接

public Socket(String host, int port, InetAddress interface, int localPort) throws UnknowHostException, IOException

public Socket(InetAddress host, int port,  InetAddress interface, int localPort) throws UnknowHostException, IOException


3 构造但不连接

public Socket()

public void connect(SocketAddress endpoint) throws IOException

public void connect(SocketAddress endpoint, int timeout) throws IOException(超过等待时间则抛出异常,默认值0表示永远等待)


三 Socket地址

Java中表示Socket地址的抽象类是SocketAddress,目前JDK中只有一个子类,即InetSocketAddress。InetSocketAddress构造方法:

public InetSocketAddress(InetAddress address , int port)

public InetSocketAddress(String host , int port)

public InetSocketAddress(int port)(该方法只指定了端口,用在服务端)

InetSocketAddress只是存储一个连接地址,并没有尝试建立连接,所以,也可以在其他的Socket中复用。


四 判断一个Socket的连接状态

1 isClosed()方法

Socket未建立连接时:false

Socket成功建立连接时:false

Socket关闭时:true


2 isConnected()方法

Socket未建立连接时:false

Socket成功建立连接时:true

Socket关闭时:true


3 判断一个Socket当前是否打开

boolean connected = socket.isConnected() && ! socket.isClosed() ;


五 Socket的选项

1 TCP_NODELAY

正常情况下,小的数据包在发送前会组合为更大的数据包,在发送另一个包前,本地主机要等待远程系统对前一个包的确认。(Nagle算法)

所以对于依赖小数据量稳定传输的程序(比如实时跟踪鼠标移动),延迟会很严重。TCP_NODELAY会打破这种缓冲模式,数据包一旦就绪,就会发送。


2 SO_LINGER

默认情况下,当socket关闭时,如果有未发送完的数据,close方法会立即返回,但系统会接管发送队列并尝试发送剩余的数据。设置SO_LINGER之后,close方法会被阻塞指定时间(setSoLinger),等待发送数据和接收确认。如果过去相应时间后数据未发送完,则丢弃数据。


3 SO_TIMEOUT

设置socket读取数据的超时时间。如果超时则会抛出InterruptedIOException异常,但是Socket仍然是连接的,程序可以捕获这个异常并再次尝试读取socket内容。


4 SO_RCVBUF 和 SO_SNDBUF

设置发送和接收缓冲区的大小。需要注意的是,即使两个缓冲区设置为不同的大小,实际上两个缓冲区的真实大小会取两个设定值中较小的一个。


5 SO_KEEPALIVE

一般在长连接中使用,开始SO_KEEPALIVE之后,客户端通过一个空闲连接发送一个数据包,以确保服务器未崩溃。


六 服务器Socket(ServerSocket)的构造

ServerSocket一共有四个构造函数,前三个构造并绑定端口,最后一个构造但不绑定端口。

如果构造函数抛出BindException,说明无法创建Socket并绑定到端口;如果抛出IOException,那么可能有两种情况:一是目标端口正在被其他Socket使用;二是尝试绑定1-1024范围内的端口但没有root权限(Unix)。


1 public ServerSocket(int port) throws BindException, IOException

将Socket绑定到本地所以网络接口的某个端口上。


2 public ServerSocket(int port, int queueLength) throws BindException, IOException

将Socket绑定到本地所以网络接口的某个端口上,并且设置Socket的队列长度。


3 public ServerSocket(int port, int queueLength, InetAddress address) throws IOException

将Socket绑定到本地某个网络接口的某个端口上,设置Socket的队列长度。


4 public ServerSocket() throws IOException

   public void bind(SocketAddress endpoint) throws IOException

   public void bind(SocketAddress endpoint, int queueLength) throws IOException

先无参构造一个ServerSocket,之后使用bind()函数,绑定一个端口。


七 ServerSocket选项

1 SO_TIMEOUT

ServerSocket设置这个选项的目的是设置accept()方法阻塞的超时时间,默认只为0,表示永不超时;ServerSocket很少设置这个选项,因为一般都会让accept()函数一直运行,从而保证ServerSocket一直对端口进行监听。


2 SO_RCVBUF

设置服务器接收端的缓冲区大小。


3 SO_REUSEADDR

是否允许一个新的Socket绑定到之前使用过的一个端口上,而此时可能还有一些发送到原Socket的数据正在网络上传输。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值