构造Socket

  Socket构造方法如下:

 Socket()
//Creates an unconnected socket, with the system-default type of SocketImpl. Socket(InetAddress address, int port)
//Creates a stream socket and connects it to the specified port number at the
//specified IP address. Socket(InetAddress host, int port, boolean stream)
//Deprecated.
//Use DatagramSocket instead for UDP transport. Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
//Creates a socket and connects it to the specified remote address on the
//specified remote port. Socket(Proxy proxy)
//Creates an unconnected socket, specifying the type of proxy, if any, that
//should be used regardless of any other settings. Socket(SocketImpl impl)
//Creates an unconnected Socket with a user-specified SocketImpl. Socket(String host, int port)
//Creates a stream socket and connects it to the specified port number on the
named host. Socket(String host, int port, boolean stream)
//Deprecated.
//Use DatagramSocket instead for UDP transport. Socket(String host, int port, InetAddress localAddr, int localPort)
//Creates a socket and connects it to the specified remote host on the specified
//remote port.

  除了第一个无参,其余构造方法都试图建立与服务器的连接,如果成功则返回Socket对象,否在抛出异常。

  根据以上构造方法来创建一个类,用于扫描主机上1-1024之间的端口是否被服务器程序监听(如果被监听,就可以返回Socket对象)。代码如下:

import java.io.IOException;
import java.net.Socket; public class PortScanner { public static void main(String[] args) {
String host="localhost";
new PortScanner().scan(host); }
public void scan(String host){
Socket socket=null;
for(int port=1;port<=1024;port++){
try{
socket=new Socket(host,port);
System.out.println("There is a server on port "+port);
}catch(IOException e){
System.out.println("Can't connect to port "+port);
}finally{
if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
} }

  2.1.1 设定等待建立连接的超时时间

    当需要设定连接超时时间时,则需要调用Socket的无参构造函数。   

Socket socket = new Socket();
//SocketAddress 提供不可变对象,供套接字用于绑定、连接或用作返回值。
SocketAddress remoteAddr = new InetSocketAddress("localhost",8000);
//超时未连接时,会抛出超时异常。
socket.connect(remoteAddr,60000);//毫秒为单位,0表示用于不超时

  2.1.2 设定服务器地址

    除了第一个无参构造函数,其余都需要提供服务器IP或主机名,以及端口号。    

 Socket(InetAddress address,int port)  //第一个参数表示主机IP地址
Socket(String host,int port) //第一个表示主机名

    InetAddress类表示服务器的IP地址,详情查看这里

  2.1.3 设定客户端地址

  一个socket对象应该包含远程服务器的IP和端口信息,也包含本地客户机的IP地址和端口信息。默认情况下,客户机的IP来自于本地主机,端口有操作系统自动分配。也可以显式的设置客户端的IP和端口。  

 Socket(InetAddress address,int port,InetAddress localAddress,int localPort)
Socket(String host,int port,int port,InetAddress localAddress,int localPort)

  2.1.4 客户机连接服务器可能出现的异常

UnKnownHostException 无法识别主机的名字或IP地址
ConnectException 服务器没有对应的端口或服务器拒绝连接
SocketTimeoutException 等待连接超时
BindException 无法与指定的本地IP或端口绑定
   
   
   
   

获取Socket信息

  以下方法可获得Socket相关信息:

 InetAddress getInetAddress()
//Returns the address to which the socket is connected. InputStream getInputStream()
//Returns an input stream for this socket. OutputStream getOutputStream()
//Returns an output stream for this socket. int getPort()
//Returns the remote port number to which this socket is connected. InetAddress getLocalAddress()
//Gets the local address to which the socket is bound. int getLocalPort()
//Returns the local port number to which this socket is bound.

关闭Socket

  部分代码如下:

if(socket!=null){
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

  Socket提供了3个状态测试方法:

boolean isBound()
//Returns the binding state of the socket. boolean isClosed()
//Returns the closed state of the socket. boolean isConnected()
//Returns the connection state of the socket.

半关闭Socket

  进程A与进程B通信时,A传输数据到B,如何告知B所有数据已经传输完毕呢?以下几个方法:

  (1) 发送一行特殊的字符串,如前一章使用的“bye”,告知输出完毕。

  (2) A先告诉B字符串的长度,在向B传输数据。

  (3) A发送完成后,关闭Socket。此时B读完数据后,在此执行read()时,该方法返回-1,如果执行BufferedReader的readLine()方法,则返回null。以此表示到达输入流末尾。

  (4) 关闭Socket的输入输出流

shutdownInput():关闭输入流

shutdownOutput():关闭输出流

对应两个状态测试方法:

  isInputShutdown()

  isOutputShutdown()

设置Socket的选项

  TCP_NODEALY:表示立即 发送数据。

  默认情况下,发送数据会先放在缓冲区,缓存区满了在发出去,并等待接收方的响应,然后再发下一批数据。这种模式适合发送大量数据,并且会得到及时响应的场合。发送小数据时这种模式速度很慢,调用setTcpNoDelay(true)可以关闭缓存区。设置之前先调用socket.getTcpNoDelay()方法查看底层是否支持TCP_NODEALY选项。

  SO_RESUSEADDR:表示是否允许重用Socket所绑定的本地地址。

  当socket执行close()方法后,底层Socket不会立刻释放本地端口,而是等待一会,确保接收到网络发送的延迟数据,然后再释放。这样可以确保这些数据不会被其他绑定到该端口的新进程接收到。为了确保Socket关闭后即使端口未被释放,其他进程也可以绑定该端口,可以调用setResuseAddress(true).

  SO_TIMEOUT:表示接受数据时的等待时间。

  设定接收数据的等待超时时间,超过后抛出异常。

  SO_LINGER:当执行close()关闭Socket时,是否立即关闭底层的Socket。

  用来控制Socket关闭后的行为。默认下,关闭Socket后,底层不会立即关闭,延迟一段时间,等待剩余数据发送完成,才会关闭底层。

  执行以下方法:socket.setSoLinger(true,0);则Socket执行close()方法后,会立即关闭底层,未发送完的数据被丢弃。

  执行以下方法:socket.setSoLinger(true,3600);表示执行close()方法后进入阻塞状态。当所有数据发送完成后或者阻塞时间超过3600秒(以秒为单位)才会返回。

  SO_SNDBUF:发送数据的缓冲区大小。

    设置输出数据的缓存区大小。

  SO_RCVBUF:接收数据的缓冲区大小。

    设置输入数据的缓存区大小。

  SO_KEEPALIVE:表示对于空闲的Socket,是否把它关闭。

  选项为true时,底层TCP会对该连接进行监视。当连接空闲状态超过2小时,本地TCP会发送一个数据包给远程Socket。如果未收到响应,则持续尝试11分钟。在12分钟内没有收到响应的话,TCP会自动关闭本地Socket。

  OOBINLINE:表示是否支持发送一个字节的TCP紧急数。

  服务类型选项

  设置服务类型:setTrafficClass(int trafficClass)

  低成本:0x02

  高可靠性:0x04

  最高吞吐量:0x08

  最小延迟:0x10

  以下代码设置请求高可靠性和最小延迟:

  socket.setTrafficClass(0x04|0x10);

送邮件的SMTP客户程序

  略

第二章 Socket用法详解的更多相关文章

  1. 第二章 IP协议详解

    第二章 IP协议详解 2.1 IP服务的特点 它为上层协议提供了无状态,无连接,不可靠的服务 名称 简介 优点 缺点 对付缺点的方法 无状态 IP通信双方不同步传输数据的状态信息 无须为保持通信的状态 ...

  2. Cobalt Strike系列教程第二章:Beacon详解

    上周更新了Cobalt Strike系列教程第一章:简介与安装,文章发布后,深受大家的喜爱,遂将该系列教程的其他章节与大家分享,提升更多实用技能! 第二章:Beacon详解 一.Beacon命令 大家 ...

  3. 【转】JAVA Socket用法详解

    一.构造Socket Socket的构造方法有以下几种重载形式: (1)Socket() (2)Socket(InetAddress address, int port)throws UnknownH ...

  4. 第三章 ServerSpcket用法详解

    构造ServerSocket ServerSocket的构造方法如下: ServerSocket() //Creates an unbound server socket. ServerSocket( ...

  5. java Socket用法详解(转)

    在客户/服务器通信模式中, 客户端需要主动创建与服务器连接的 Socket(套接字), 服务器端收到了客户端的连接请求, 也会创建与客户连接的 Socket. Socket可看做是通信连接两端的收发器 ...

  6. Socket用法详解

    在客户/服务器通信模式中,客户端需要主动创建与服务器的Socket(套接字),服务端收到了客户端的请求,也会创建与客户端连接的Socket. Scoket可以看作两端通信的收发器,服务端和客户端都通过 ...

  7. 第二章 Python数据类型详解

    基本概念 迭代(iteration):如果给定一个list或tuple,我们可以通过for循环来遍历,这种遍历我们称为迭代(iteration) 可变:value改变,id不变,可变类型是不可hash ...

  8. Java语言Socket接口用法详解

    Socket接口用法详解   在Java中,基于TCP协议实现网络通信的类有两个,在客户端的Socket类和在服务器端的ServerSocket类,ServerSocket类的功能是建立一个Serve ...

  9. “全栈2019”Java第二十九章:数组详解(中篇)

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

随机推荐

  1. Git 最新版本2.20.1 安装及配置

    我们先去官网下载地址,去下载. https://git-scm.com/downloads 1. 2. 3. 双击 Git-2.20.1-64-bit.exe 安装 4. 5. 6. 7. 8. 9. ...

  2. 20155229 2016-2017-2 《Java程序设计》第九周学习总结

    20155229 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 第十六章 JDBC(Java DataBaseConnectivity)即java数据库连接 ...

  3. 20155327 java第四周学习笔记

    20155327 java第四周学习笔记 五六章知识整理 1子类与父类 父类是接口或者是抽象类,子类必须继承自父类. 2子类的继承性 在Java中,通过关键字extends继承一个已有的类,被继承的类 ...

  4. BZOJ1026_windy数_KEY

    题目传送门 数位DP,其实只要求1~A-1和1~B就可以了.两数相减即为答案. 考虑怎们求1~A. 设f[i][j]表示到第i位,为j的windy数总数. 由前一位差值大于1的方程转移. 但是统计答案 ...

  5. Codeforces 862D. Mahmoud and Ehab and the binary string (二分)

    题目链接:Mahmoud and Ehab and the binary string 题意: 一道交互题,首先给出一个字符串的长度l.现在让你进行提问(最多15次),每次提问提出一个字符串,会返回这 ...

  6. luogu1117 [NOI2016]优秀的拆分

    luogu1117 [NOI2016]优秀的拆分 https://www.luogu.org/problemnew/show/P1117 后缀数组我忘了. 此题哈希可解决95分(= =) 设\(l_i ...

  7. 单元测试——测试神器,testng

    为什么用它 建议使用 TestNG 作为 Java 项目的主要单元测试框架,因为 TestNG 在参数化测试.依赖测试以及套件测试(组)方面功能更加强大.TestNG 意味着高级的测试和复杂的集成测试 ...

  8. UWP 轨道视图Orbit View

    先看一下效果吧 这是我的Music Tags App里面的效果图,当然你也可以做的比我的更炫. 其实这个效果的实现来自于控件UWP Community Toolkit的OrbitView,所以大家要多 ...

  9. bootstrap学习笔记(5)

    Bootstrap输入框组 主要记住一个原则 创建输入框的步骤 把前缀或后缀元素放在一个带有 class .input-group 的 <div> 中. 接着,在相同的 <div&g ...

  10. Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介.Java REST Client.Java Client.Spri ...