C/S通信架构中,客户端要主动与服务端建立连接,这个链接就是Socket套接字.服务端收到连接请求后,也会开启Socket记录与客户端的链接.C/S两端都要建路Socket才能正常收发数据.

一.构造Socket

(1)new Socket ( )

(2)new Socket ( InetAddress addres,int port )

(3)new Socket ( String hostnamme,int port )

以上3种创建socket的构造函数,除第一种外,都要试图简历与服务器的连接,连接成功返回Socket对象,连接失败,抛出IOException

/** 扫描主机1-1024之间的端口,判断这些端口上是否有程序进行监听
* PortScanner与1-1024端口建立Socket对象,建立成功说明该端口上有程序进行监听
*/
public class PortScanner {
public static void main(String[] args) {
Socket socket = null;
for (int i = 1; i < 1024; i++) {
try {
socket = new Socket("localhost",i);
System.out.println(i+"端口有程序在监听");
} catch (IOException e) {
System.out.println(i+"端口空闲");
}finally {
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

二. 建立连接超时时间的Socket

    默认情况下,与服务端链接建立Socket时,会一直阻塞,直到服务端的操作系统返回信息表示连接建立,或抛出异常表示该端口无应用程序响应.受网络影响,Socket返回会有很长等待时间,因此可以设置建立连接产生Socket的阻塞时间(超时时间)

Socket socket = new Socket();
socket.connect(new InetSocketAddress("localhost",8080),60*1000); //一分钟超时时间

三. Socket信息

getInetASddress();     // 获取与之连接的服务端ip
getPort(); // 获取与之连接的服务端port
getLocalAddress();
getLocalPort(); // 客户端为该进程开启的端口

四. Socket关闭

当客户端与服务端通信结束,客户端应及时关闭Socket,释放为其开启的端口标识和其他资源

finally {    // 释放操作放在finally块中
try {
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}

Socket可以只关闭输入流或者输出流

shutdownInput();
shutdownOutput();

五. Socket选项

**1. TCP_NODELAY **

    Socket连接发送数据默认采用Negale算法,即发送方发送的数据先缓存在底层缓冲区,当缓冲区满后,再将数据发送出去.这种方法减少了数据的传输次数来提高通信效率,适合发送大量数据,且接收方会及时相应的场景下.

    若发送方连续发送小批量数据,这些数据不会立刻发送而是会先缓存起来,导致实时响应速度很慢;例如客户端鼠标移动的信息需要实时发送到服务器上,采用Negale算法,会大大降低实时响应速度.

    关闭Negale发送算法 : setTcpNoDelay();

**2. SO_RESUSEADDR: **

    socket的close()方法触发后,操作系统不会立刻释放该Socket所占端口,而是等一段时间,确保收到网络上发来的延迟数据,并不对该数据做任何处理.该段时间过后才释放端口.防止被其他恰巧绑定到相同端口的新进程收到该延迟数据.

    客户端来讲,操作系统为进程随机开启端口,一般不会使得新进程绑定到老进程的端口.对于服务端来说,进程挂掉后立即重启会重启失败,因为底层端口未被释放,而服务端进程应该响应客户端发来的延迟数据,所以服务端进程可以设置端口重用(setResuseAddress(true)).只有新老进程都设置了SO_RESUSEADDR,才能立刻端口重用

//SO_RESUSEADDR要在Socket未绑定本地port钱调用,否则该选项设置无效,用如下方式开启socket链接
public static void main(String[] args) throws IOException {
Socket socket = new Socket();
socket.setReuseAddress(true);
socket.connect(new InetSocketAddress("localhost",8080),60*1000); //一分钟超时时间
}

3. SO_TIEMOUT

byte[] buff = new byte[1024];
InputStream in = socket.getInputStream();
in.read(buff);

若没有数据可读,则会一直阻塞,setTimeout(60*1000),设置读阻塞的超时时间为1分钟

4. SO_LINGER

Socket的close方法会立即返回,但底层端口未被立即释放,会延迟一段时间,等到所有数据发送,且接收到所有返回的确认包后,才真正关闭.socket的setSoLinger(true,3600),设置close()方法自多阻塞3600秒,若还有数据未被发送,则丢弃该部分数据

5. SO_KEEPALIVE

默认情况,Socket的KEEPALIVE选项为false,客户端发完消息,如果不手动调用close(),则socket会一直存在,不释放资源.setKeepAlive(true)后,当通信两端没有数据传输时,操作系统发现该socket已超过2小时空闲,则会自动发送一个测试包给远程机器,测试包会持续尝试11分钟,若在12分钟内没收到远程机器发来的确认包,操作系统则会自动关闭本地Socket,释放资源

**6. OOBINLINE **

当setOOBLine(true),操作系统支持发送紧急数据,sendUrgent(int data)发送一个字节的紧急数据.默认情况OOBINLINE为false.但是接收方仍会把改紧急数据放到普通数据的队列中,紧急数据到来,接收方不会得到任何通知,所以接收方无法区分普通数据和紧急数据,只能按照相同方式处理

二. Socket用法的更多相关文章

  1. sqlalchemy(二)高级用法

    sqlalchemy(二)高级用法 本文将介绍sqlalchemy的高级用法. 外键以及relationship 首先创建数据库,在这里一个user对应多个address,因此需要在address上增 ...

  2. WIN 下的超动态菜单(二)用法

    WIN 下的超动态菜单(一)简介 WIN 下的超动态菜单(二)用法 WIN 下的超动态菜单(三)代码 作者:黄山松,发表于博客园:http://www.cnblogs.com/tomview/     ...

  3. class的二般用法

    一般来说,class就是给一堆元素添加样式的,但是还有二般的用法,就是用来作为一个开关,来切换他的子孙元素的样式.举个例子: <ul> <li><span>1< ...

  4. linux内核中的文件描述符(二)--socket和文件描述符

    http://blog.csdn.net/ce123_zhouwei/article/details/8459730 Linux内核中的文件描述符(二)--socket和文件描述符 Kernel ve ...

  5. Java中的Socket用法

    转发链接:https://www.cnblogs.com/zhanglei93/p/6217384.html (1)Java中的Socket用法 Java中的Socket分为普通的Socket和Nio ...

  6. java Socket用法详解(转)

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

  7. 【转】JAVA Socket用法详解

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

  8. Fiddler (二) Script 用法

      通过前一篇博客 [Fiddler教程], 我们了解了Fiddler的基本用法,  现在我们来看看Fiddler的高级用法. Fiddler Script.   Fiddler中的script 可以 ...

  9. Socket用法详解

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

随机推荐

  1. ZOJ 1110 Dick and Jane

    原题链接 题目大意:Dick和Jane的年龄之和等于他们宠物的年龄,宠物之间的年龄关系XXX. 解法:小学奥数题目,枚举法. 参考代码: #include<iostream> #inclu ...

  2. Spring的声明试事务

    1 在配置文件中加入: <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.spring ...

  3. C陷阱与缺陷 2

    1,数组 对数组只能进行两种操作,1确定数组的大小,2获得数组第一个元素的指针,其他的操作均是通过指针来实现的. 1 2 3 4 5 6 7 8 9 #include <stdio.h> ...

  4. spark新能优化之广播共享数据

    如果你的算子函数中,使用到了特别大的数据,那么,这个时候,推荐将该数据进行广播.这样的话,就不至于将一个大数据拷贝到每一个task上去.而是给每个节点拷贝一份,然后节点上的task共享该数据. 这样的 ...

  5. Linux 安装rar解压工具

    下载RAR安装包: http://www.rarsoft.com/download.htm 我的是CentOS 64位: wget http://www.rarsoft.com/rar/rarlinu ...

  6. IOS中打开应用实现检查更新的功能

    //检查更新页面 - (void)Renew{        NSDictionary *infoDic = [[NSBundle mainBundle]infoDictionary];        ...

  7. Httptunnel教程

    hts --forward-port localhost:22 80 htc -F 6789 192.168.10.1:80

  8. 黑马程序员——JAVA基础之String和StringBuffer

    ------- android培训.java培训.期待与您交流! ---------- String类: 字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String str = &quo ...

  9. SpringMVC @Value取值(取properties属性文件的属性值)

    @Controller @RequestMapping("/reg") public class RegController extends BaseController { @V ...

  10. Java Warmup

    http://www.brendangregg.com/blog/2016-09-28/java-warmup.html