(转自http://www.cnblogs.com/ggjucheng/archive/2012/01/06/2314679.html)

( http://docs.oracle.com/javase/tutorial/java/package/summary-package.html)

Java Socket的api可能很多人会用,但是Java Socket的参数可能很多人都不知道用来干嘛的,甚至都不知道有这些参数。

backlog

用于ServerSocket,配置ServerSocket的最大客户端等待队列。等待队列的意思,先看下面代码

public class Main {
public static void main(String[] args) throws Exception {
int port = 8999;
int backlog = 2;
ServerSocket serverSocket = new ServerSocket(port, backlog);
Socket clientSock = serverSocket.accept();
System.out.println("revcive from " + clientSock.getPort());
while (true) {
byte buf[] = new byte[1024];
int len = clientSock.getInputStream().read(buf);
System.out.println(new String(buf, 0, len));
}
}
}

这段测试代码在第一次处理一个客户端时,就不会处理第二个客户端,所以除了第一个客户端,其他客户端就是等待队列了。所以这个服务器最多可以同时连接3个客户端,其中2个等待队列。大家可以telnet localhost 8999测试下。

这个参数设置为-1表示无限制,默认是50个最大等待队列,如果设置无限制,那么你要小心了,如果你服务器无法处理那么多连接,那么当很多客户端连到你的服务器时,每一个TCP连接都会占用服务器的内存,最后会让服务器崩溃的。

另外,就算你设置了backlog为10,如果你的代码中是一直Socket clientSock = serverSocket.accept(),假设我们的机器最多可以同时处理100个请求,总共有100个线程在运行,然后你把在100个线程的线程池 处理clientSock,不能处理的clientSock就排队,最后clientSock越来越多,也意味着TCP连接越来越多,也意味着我们的服务 器的内存使用越来越高(客户端连接进程,肯定会发送数据过来,数据会保存到服务器端的TCP接收缓存区),最后服务器就宕机了。所以如果你不能处理那么多 请求,请不要循环无限制地调用serverSocket.accept(),否则backlog也无法生效。如果真的请求过多,只会让你的服务器宕机(相 信很多人都是这么写,要注意点)

TcpNoDelay

禁用纳格算法,将数据立即发送出去。纳格算法是以减少封包传送量来增进TCP/IP网络的效能,当我们调用下面代码,如:

Socket socket = new Socket();  
socket.connect(new InetSocketAddress(host, 8000));
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
String head = "hello ";
String body = "world\r\n";
out.write(head.getBytes());
out.write(body.getBytes());

我们发送了hello,当hello没有收到ack确认(TCP是可靠连接,发送的每一个数据都要收到对方的一个ack确认,否则就要重发)的时 候,根据纳格算法,world不会立马发送,会等待,要么等到ack确认(最多等100ms对方会发过来的),要么等到TCP缓冲区内 容>=MSS,很明显这里没有机会,我们写了world后再也没有写数据了,所以只能等到hello的ack我们才会发送world,除非我们禁用 纳格算法,数据就会立即发送了。

纳格算法参考:http://zh.wikipedia.org/wiki/%E7%B4%8D%E6%A0%BC%E7%AE%97%E6%B3%95

另外有一篇讲解纳格算法和delay ack的文章(挺不错的):http://blog.csdn.net/frankggyy/article/details/6624401

SoLinger

当我们调用socket.close()返回时,socket已经write的数据未必已经发送到对方了,例如

Socket socket = new Socket();  
socket.connect(new InetSocketAddress(host, 8000));
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
String head = "hello ";
String body = "world\r\n";
out.write(head.getBytes());
out.write(body.getBytes());
socket.close();

这里调用了socket.close()返回时,hello和world未必已经成功发送到对方了,如果我们设置了linger而不小于0,如:

bool on = true;
int linger = 100;
....
socket.setSoLinger(boolean on, int linger)
......
socket.close();

那么close会等到发送的数据已经确认了才返回。但是如果对方宕机,超时,那么会根据linger设定的时间返回。

UrgentData和OOBInline

TCP的紧急指针,一般都不建议使用,而且不同的TCP/IP实现,也不同,一般说如果你有紧急数据宁愿再建立一个新的TCP/IP连接发送数据,让对方紧急处理。

所以这两个参数,你们可以忽略吧,想知道更多的,自己查下资料。

SoTimeout

设置socket调用InputStream读数据的超时时间,以毫秒为单位,如果超过这个时候,会抛出java.net.SocketTimeoutException。

KeepAlive

keepalive不是说TCP的常连接,当我们作为服务端,一个客户端连接上来,如果设置了keeplive为true,当对方没有发送任何数据
过来,超过一个时间(看系统内核参数配置),那么我们这边会发送一个ack探测包发到对方,探测双方的TCP/IP连接是否有效(对方可能断点,断网),
在Linux好像这个时间是75秒。如果不设置,那么客户端宕机时,服务器永远也不知道客户端宕机了,仍然保存这个失效的连接。

SendBufferSize和ReceiveBufferSize

TCP发送缓存区和接收缓存区,默认是8192,一般情况下足够了,而且就算你增加了发送缓存区,对方没有增加它对应的接收缓冲,那么在TCP三握
手时,最后确定的最大发送窗口还是双方最小的那个缓冲区,就算你无视,发了更多的数据,那么多出来的数据也会被丢弃。除非双方都协商好。

以上的参数都是比较重要的Java Socket参数了,其他就不另外说明了。

Java Socket重要参数讲解的更多相关文章

  1. java socket 的参数选项解读(转)

    java socket中有很多参数可以选择,这篇博客的目的是沉淀出这些参数的语义和用法,供自己以后查阅. 1.java socket参数选项总览 在JDK1.6中有如下参数选项: 1 public f ...

  2. java socket 的参数选项解读

    java socket中有很多参数可以选择,这篇博客的目的是沉淀出这些参数的语义和用法,供自己以后查阅. 1.java socket参数选项总览 在JDK1.6中有如下参数选项: public fin ...

  3. Java Socket编程 深入讲解?你之前真的学懂了吗

    很多人学习Socket往往会碰到这样哪样的问题,可以看看下面,加深理解.能看懂多少看懂多少. Socket是Java网络编程的基础,了解还是有好处的,这篇文章主要讲解Socket的基础编程.Socke ...

  4. 简单的例子 关于Java内存管理的讲解

    我想做的是,逐行读取文件,然后用该行的电影名去获取电影信息.因为源文件较大,readlines()不能完全读取所有电影名,所以我们逐行读取. 就这段代码,我想要在位置二处使用base64,然后结果呢? ...

  5. java socket API

    java.net类 Socket java.lang.Object java.net.Socket 直接已知子类: SSLSocket public class Socketextends Objec ...

  6. Java Socket发送与接收HTTP消息简单实现

    在上次Java Socket现实简单的HTTP服务我 们实现了简单的HTTP服务,它可以用来模拟HTTP服务,用它可以截获HTTP请求的原始码流,让我们很清楚的了解到我们向服务发的HTTP消息的结 构 ...

  7. Java socket中关闭IO流后,发生什么事?(以关闭输出流为例)

    声明:该博文以socket中,关闭输出流为例进行说明. 为了方便讲解,我们把DataOutputstream dout = new DataOutputStream(new BufferedOutpu ...

  8. 如何为可扩展系统进行Java Socket编程

    从简单I/O到异步非阻塞channel的Java Socket模型演变之旅 上世纪九十年代后期,我在一家在线视频游戏工资工作,在哪里我主要的工作就是编写Unix Unix Berkley Socket ...

  9. JAVA Socket连接服务器时可能抛出的异常

    1.UnknownHostException:host(非ip)无法识,就会报该异常,www.google.com.hk这个虽然也ping不通,但是不会报该错,因为他是一个确实存在的域名.他会报Con ...

随机推荐

  1. ubuntu ftp 建立匿名用户 [转]

    转自:http://www.cnblogs.com/cocoajin/p/3761414.html ubuntu server vsftpd 匿名用户上传下载及目录设置 1:vsftpd服务器安装: ...

  2. Linux下php5.3.3安装mcrypt扩展

    具体操作: 一.下载软件包 1.下载php(版本要与系统安装的一致) http://pan.baidu.com/s/1mifTbfE 2.下载libmcrypt(安装mcrypt需要此软件包) htt ...

  3. cmd 获取 拖拽文件名

    1. @echo off & setlocal enableDelayedExpansion set a= set /p a=Please drag your txt file for spl ...

  4. Appuim学习路-Appuim介绍

    (学一个东西,总的知道它支持什么.为什么要选择它吧?所以我就去看github上的介绍了.发现大家介绍的来源大多来自于此)   Appium是一个开源的自动化框架,是跨平台的,允许所有平台使用同一套AP ...

  5. 获取RequestMapping注解中的属性

    参考:https://www.cnblogs.com/2013jiutian/p/7294053.html @RequestMapping("/value1") @Controll ...

  6. 对实体类的CRUD操作

    --------------------siwuxie095 对实体类的 CRUD 操作 1.创建数据库和表 (1)创建一个 MySQL 连接:mybatis_conn (2)创建一个数据库:myba ...

  7. Java计算图的匹配率

    2016-07-02 大概意思就是这样了,代码里我貌似没有计算最后一步,但是原理都是一样的.....R1有5个点P1有四个点,他们共同的点是4个,那就是共同点4*4/(R1的5个点*P1的四个点就是0 ...

  8. 从文件中读取字符-多次调用read characters from file multiple calls

    [抄题]: 接口:int read4(char * buf)一次从文件中读取 4 个字符.返回值是实际读取的字符数. 例如,如果文件中只剩下 3 个字符,则返回 3.通过使用read4 接口,实现从文 ...

  9. B/S与C/S的比较

    1.C/S需要安装客户端软件,比如我们的qq就是C/S模式下的软件.如果使用这些软件我们必须先要下载客户端软件.如果软件更新了,就需要下载新的客户端进行更新. 2.B/S无需安装客户端软件,比如我们的 ...

  10. 【转】HttpApplication的认识与加深理解

    原文:http://www.cnblogs.com/whtydn/archive/2009/10/16/1584584.html HttpApplication对象是经由HttpApplication ...