`

java socket 参数(转)

 
阅读更多

转自:http://www.cnblogs.com/ggjucheng/archive/2012/01/06/2314679.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 连接池实现是提高网络应用性能和效率的关键技术之一。在高并发的网络环境中,频繁地创建和销毁Socket连接会导致大量的系统资源浪费,影响整体性能。为了解决这个问题,开发人员通常会使用连接池来管理和...

    java socket使用加密协议传输对象

    ### Java Socket 使用加密协议传输对象:深入解析与实践 在当今互联网时代,数据安全成为企业和个人用户关注的焦点。在Java开发中,Socket编程是一种常见的网络通信方式,它允许不同计算机上的应用程序通过网络进行...

    java使用Socket类接收和发送数据

    在Java中,可以使用`Socket(String host, int port)`构造函数创建一个Socket实例,其中host参数是服务器的IP或域名,port参数是服务器的端口号。例如: ```java Socket socket = new Socket("www.example.com", 80...

    JAVA Socket远程执行任务

    - 在这个例子中,服务器可能执行了类似`java -jar FindWordCount.jar <命令>`的命令,其中`<命令>`是客户端发送的参数。 5. **结果返回**: - 服务器在执行完命令后,可以通过Socket的InputStream读取程序的输出...

    Java Socket聊天和文件传输工具(更新)

    Java Socket技术是网络编程中的重要组成部分,主要用于实现客户端与服务器之间的通信。在这个“Java Socket聊天和文件传输工具”中,开发者结合了实时聊天和文件传输的功能,使得用户可以在进行文字交流的同时,无缝...

    java socket编程

    Java Socket编程是Java平台中用于实现网络通信的核心API,它基于TCP/IP协议栈,提供了低级别的、面向连接的、可靠的字节流通信。在本文中,我们将深入探讨Java Socket编程的关键概念、工作原理以及如何创建服务端和...

    Java Socket源码

    - Java Socket API的官方文档,详细解释了各个方法的功能、参数和返回值。 - 相关设计模式或最佳实践,指导如何高效地使用Socket进行网络编程。 - Socket编程中可能出现的问题和解决方案。 9. **Exe.rar** 文件...

    最近开发的一个 java socket项目

    在本项目中,我们关注的是一个基于Java Socket编程的开发实例。Java Socket是Java网络编程的基础,它提供了在网络中两台计算机之间建立通信链接的能力。在这个"最近开发的一个 Java socket项目"中,开发者可能实现了...

    自己写的Java Socket服务端

    实现这个功能,我们可以创建一个`Thread`子类,将Socket对象作为参数传递,然后在新线程中处理输入输出。 在`socket_test`压缩包中,可能包含以下文件: - `Server.java`:服务器端主程序,创建并启动ServerSocket...

    java socket连接池

    Java Socket连接池是一种优化网络通信性能的技术,它允许应用程序复用已经建立的Socket连接,从而减少因频繁创建和销毁Socket连接而产生的开销。在高并发的服务器环境中,Socket连接池能够有效地提升系统效率和响应...

    java socket查询数据库实现登录验证.zip

    Java Socket编程是网络编程的基础,它允许两个应用之间建立直接的、双向的通信。在这个"java socket查询数据库实现登录验证"的示例中,我们将深入探讨如何使用Java Socket连接到数据库,进行用户登录验证。 首先,...

    java socket多线程文件传输实例项目

    Java Socket多线程文件传输实例项目是一个典型的网络编程应用场景,主要涉及了Socket编程、多线程处理以及文件I/O操作等关键知识点。在这个项目中,开发者利用Java的Socket API实现了一个能够支持多个客户端同时进行...

    java socket编程实例(出自《java大学教程》)

    `Socket`的构造函数接受`InetAddress`和端口号作为参数。 - 服务器(ServerSocket):使用`ServerSocket`类创建监听特定端口的服务器。`ServerSocket`的构造函数指定监听的端口号。 - 数据交换:`Socket`和`...

    java socket 客户端和服务端例子

    在Java中,服务类通常是一个独立的类,它接收Socket实例作为参数,然后通过Socket的输入和输出流进行数据交换。 在实际开发中,为了提高程序的健壮性和可维护性,我们还会考虑异常处理、多线程(让服务端能够同时...

    java socket 编程,Java socket 编程实例

    ### Java Socket编程详解及实例分析 #### 一、Socket编程基础概述 在计算机网络通信领域,Socket编程是一种广泛使用的通信方式。它为不同主机上的进程提供了双向通信的能力,是网络编程的基础之一。Java语言提供了...

    JAVA UDPSocket代码

    在Java编程语言中,UDP(User Datagram Protocol)Socket是实现基于无连接网络通信的重要工具。UDP是一种无连接的传输层协议,它不保证数据的顺序、可靠性和完整性,但具有低延迟和高效率的特点,适合实时数据传输...

    Java socket 的参数选项解读

     1、java socket参数选项总览  在JDK1.6中有如下参数选项: 1 public final static int TCP_NODELAY = 0x0001; 2 3 public final static int SO_BINDADDR = 0x000F; 4 5 public final static int SO_...

    Java Socket编程笔记_动力节点Java学院整理

    异常处理在Java Socket编程中扮演着重要角色。主要涉及四种异常类型: 1. `UnknownHostException`: 表示主机名或IP地址无法解析,通常是因为网络不可达或者主机名不存在。 2. `ConnectException`: 当尝试连接到...

    JAVA SOCKET实现CMPP2.0

    Java Socket实现CMPP2.0是中国移动互联网短信网关接口协议的一种编程实践。CMPP(China Mobile Peer to Peer)是中国移动推出的一种高效、稳定、可靠的通信协议,主要用于短信业务,如点对点短信、上行短信、下行...

    java quickserver,quickserver,java socket

    QuickServer的核心是基于Java Socket API构建的,因此理解Java Socket编程对于使用这个框架至关重要。 Java Socket是Java提供的一个低级网络通信接口,允许两个网络应用程序之间进行双向通信。Socket编程主要包括...

Global site tag (gtag.js) - Google Analytics