java socket 属性设置
来源:互联网 发布:韩国人化妆品知乎 编辑:程序博客网 时间:2024/05/17 11:06
//解析服务器地址和端口号
int dotPos = ipAddr.indexOf(':');
String ip = ipAddr.substring(0, dotPos).trim();
int port = Integer.parseInt(ipAddr.substring(dotPos+1).trim());
InetSocketAddress endpoint = new InetSocketAddress(ip , port);
Socket socket = null;
OutputStream out = null;
InputStream in = null;
try {
socket = new Socket();
//设置发送逗留时间2秒 //中断后未传输数据可传输的时间(秒),defalut false
socket.setSoLinger(true, 2);
//设置InputStream上调用 read()阻塞超时时间2秒
socket.setSoTimeout(2000);
//对于Socket和SeverSocket如果需要指定缓冲区大小,必须在连接之前完成缓冲区的设定。
//设置socket发包缓冲为32k;
socket.setSendBufferSize(32*1024);
//设置socket底层接收缓冲为32k
socket.setReceiveBufferSize(32*1024);
//关闭Nagle算法.立即发包
socket.setTcpNoDelay(true);
//连接服务器
socket.connect(endpoint);
//获取输出输入流
out = socket.getOutputStream();
in = socket.getInputStream();
//输出请求
out.write(datas);
out.flush();
//接收应答
BufferedReader br = new BufferedReader( new InputStreamReader(in) ,
4096);
StringWriter received = new StringWriter(4096);
char[] charBuf = new char[4096];
int size =0;
char lastChar = 0;
do {
System.out.println(charBuf);
size = br.read(charBuf , 0 , 4096);
System.out.println(size);
lastChar = charBuf[size-1];
if(lastChar == 0){
received.write(charBuf, 0, size - 1);
}
//System.out.println(received.toString());
}while(lastChar != 0);
return received.toString();
} finally {
if (out != null) {
try {
out.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
if (in != null) {
try {
in.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
在创建Socket后,系统会为新创建的套接字分配缓冲区空间。这时套接字已经具有了输入缓冲区和输出缓冲区。 缓冲区大小需要根据具体情况进行设置,一般要低于64K(TCP能够指定的最大负重载数据量,TCP的窗口大小是由16bit来确定的),增大缓冲区可以增大网络I/O的性能,而减少缓冲区有助于减少传入数据的backlog(就是缓冲长度,因此提高响应速度)。
对于Socket和SeverSocket如果需要指定缓冲区大小,必须在连接之前完成缓冲区的设定。
对于缓冲区空间的设定,要根据具体情况来定,如果存在大量的长信息(比如文件传输),将缓冲区定义的大些,可能更好的利用网络资源,如果更多的是短信息(比如聊天消息),使用小的缓冲区可能更好些,这样刷新的速度会更快。一般系统默认的缓冲大小是8*1024。除非对自己处理的情况很清晰,否则请不要随意更改这个设置。
http://blog.sina.com.cn/s/blog_616e189f0100s3px.html
TCP 调优
TCP(Transmission Control Protocol)使用一个"拥塞窗口"来判断每次应该发送多少包到网络。拥塞窗口越大,吞吐量越高。拥塞窗口是由TCP的“慢启动”和“拥塞回避”算法共同决定的。而最大拥塞窗口和Socket的缓冲区大小有关。每一个Socket缓冲区都有一个默认的大小,但可以在程序中进行修改(如上面的操作)。一些操作系统有一个内核强制的最大缓冲区大小,这需要设置操作系统参数进行修改。
为了得到最大的吞吐量,必须对TCP socket的缓冲区大小进行调优。如果缓冲区设置的太小,则TCP的拥塞窗口就不会完全开启,这是发送者是瓶颈;如果缓冲区设置得太大,则发送者可能让接受者溢出,这时会发生丢包和拥塞窗口减半/关闭的可能。如果用充足的内存,大的发送者窗口也不是很大的问题。
计算TCP缓冲区大小
- 17520 bytes / 0.04 seconds = 3.5 Mbits / second
- Mac OS X 是64K,所以其能达到 65936 B / 0.04 s = 13Mb / s
设置TCP缓冲区大小
设置最大TCP缓冲区
# increase TCP maximum buffer sizenet.core.rmem_max = 16777216net.core.wmem_max = 16777216# increase Linux autotuning TCP buffer limits# min, default, and maximum number of bytes to usenet.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216
其他系统下可以参照:http://fasterdata.es.net/host-tuning/注意
http://blog.csdn.net/s_yangbin/article/details/9128321
经测试,当服务器端设置缓冲区为1MB时,系统只把缓冲区设置为了127KB,应该是默认的最大值。经过设置最大TCP缓冲区后,
ServerSocket ss = new ServerSocket(port);
Executor service = Executors.newCachedThreadPool(); // Dispatch svc
// Run forever, accepting and spawning a thread for each connection
while (true) {
Object[] obj = hmDownTotalSize.keySet().toArray();
if (obj.length > 100) {
hmDownTotalSize.clear();
}
Socket socket = ss.accept();
SocketAddress remoteAddress = socket.getRemoteSocketAddress();
String ipAddress = remoteAddress + "";
ipAddress = ipAddress.substring(1, ipAddress.indexOf(":"));
if (StringServer.hmDownTotalSize.get(ipAddress) == null) {
StringServer.hmDownTotalSize.put(ipAddress, downTotalSize);// 设置全局默认的数据包大小
}
socket.setReceiveBufferSize(downBufferUnit);
socket.setSendBufferSize(downBufferUnit);
int receiveBufferSize = socket.getReceiveBufferSize();
int sendBufferSize = socket.getSendBufferSize();
final LogSvr logSvr = new LogSvr();
final File tmpLogFile = new File("speedTest.log");
StringBuffer log = new StringBuffer();
log.append(
"\n" + ipAddress + "----------the socket's created.\n")
.append(ipAddress
+ "----------the socket's receiveBufferSize is--- "
+ receiveBufferSize / 1024 + " KB\n")
.append(ipAddress
+ "----------the Socket's sendBufferSize---------"
+ sendBufferSize / 1024 + " KB\n");
logSvr.logMsg(tmpLogFile, log.toString());
service.execute(new EchoProtocol(socket));
另外,你调用send不表示你的数据会立即发出去,当前能发送多少数据取决于:1.nagle算法是否打开,2.内核里为发送socket准备的发送缓存大小(协议栈需要拷贝一次发送数据以便丢包时重传),3.对方宣告的接收窗口大小,4.自己目前的拥塞窗口的大小。其它应该还有一些影响因素。这还只是在TCP层。IPv4的话还有一个IP包65536(64KB)的硬限制,以及链路层的MTU的限制。总之从send的角度看应该没有办法确定你从网卡出去的下一帧,或者传给网卡的下一个IP包或者走到网络层的下一个TCP包是多大的,而你也不需要知道这些。如果非要强制一个包的大小,那么用UDP吧,只是你可能就需要自己维护重传,包的顺序,以及MTU探测这些事情了。
从缓冲上看阻塞与非阻塞socket在发送接收上的区别
http://wenku.baidu.com/view/7ecc3b6d561252d380eb6e28.html
- java socket 属性设置
- java socket 属性设置
- 设置Socket的属性
- 设置socket的属性
- socket属性设置
- socket属性设置函数总结
- 设置socket描述符SO_REUSEADDR属性
- socket属性设置与初始化操
- socket属性设置与初始化操作
- Java打印设置属性
- java 设置系统属性
- java socket的超时设置
- Socket Java设置超时时间
- Socket Java设置超时时间
- java JTable表头属性设置
- java代码动态设置属性
- Android Socket 编程简单实现及 属性设置
- libevent (一) socket属性设置与初始化操作
- No package nginx available. |一次解决一个问题
- 21天效应
- 配置纯净版Debian
- UIAlertView 添加textview。
- linux tomcat部署含有matlab画图打包的java web程序
- java socket 属性设置
- android 电池(二):android关机充电流程、充电画面显示
- 单链表逆转
- c++字符串简单加密
- Juniper DIP MIP VIP有什么区别
- Java异常的总结-----黑马程序员
- android 电池(三):android电池系统
- 推荐系统论文分类推荐
- X264源程序分析(x264_slice_write)——学习笔记(1)