构造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. apple remote desktop

    下面就是重点了: 1.下载v 3.7.2版本 :http://pan.baidu.com/s/1jGmrhuI   密码:vg2r 序列号: XARD-030-000-N-LXC-RP7-FBX-23 ...

  2. c++MFC工程修改在共享DLL中使用MFC为使用标准Windows库的解决办法

    由于创建MFC工程时,默认是在共享DLL中使用MFC,如果将此选项改成使用标准Windows库,会报如下错误 c:\program files\microsoft visual studio 9.0\ ...

  3. JMeter入门教程

    转自 http://blog.csdn.net/w565911788/article/details/7629787 1.Jmeter 概要描叙 jmeter 是一款专门用于功能测试和压力测试的轻量级 ...

  4. 25-[jQuery]-ajax

    1.什么是AJAX AJAX = 异步的javascript和XML(Asynchronous Javascript and XML) 简言之,在不重载整个网页的情况下,AJAX通过后台加载数据,并在 ...

  5. python爬取快手ios端首页热门视频

    最近快手这种小视频app,特别的火,中午吃过午饭,闲来无聊,想搞下快手的短视频,看能不能搞到. 于是乎, 打开了fiddler,开始准备抓包, 设置代理,重启,下一步,查看本机ip 手机打开网络设置 ...

  6. 在腾讯ubuntu云服务器上面部署asp.net core 2.1网站

    微软以后的政策肯定是在开源和跨平台这一块,所以最近在学习asp.net core 2.1,查看市面上面大部分的把asp.net core部署在Linux后,决定亲自实验一番,不操作不知道,居然最新版本 ...

  7. 初学者浅谈我对领域驱动设计(DDD)的理解

    一.为什么要学习领域驱动设计 如果你已经设计出了优雅而万能的软件架构,如果你只是想做一名高效的编码程序员,如果你负责的软件并不复杂,那你确实不需要学习领域驱动设计. 如果用领域驱动设计带来的收获: 能 ...

  8. Java 中的接口

    接口概念 接口可以理解为一种特殊的类,由全局常量和公共抽象方法组成.类是一种具体实现体,而接口定义了某一些类所要遵守的规范,接口不必关心这些类的内部数据,也不关心这些类里方法的实现细节,它只规定这些类 ...

  9. UnityEditor扩展-Shader浏览器

    1. 用途 用于浏览项目所有Shader被使用的情况 2. 界面说明 Ignore Directory:添加不搜索的文件夹,不添加默认搜索全部 Find按钮:开始搜索 Used Shaders:已被使 ...

  10. java IO流 对文件操作的代码集合

    Io流 按照分类 有两种分类 流向方向: 有输入流和输出流 按照操作类型有:字节流和字符流 按照流向方向 字节流的一些操作 //读文件 FileInputStream fis = new FileIn ...