these days I'm confused about the Tcp performance while using java socket. In fact the java code is very simple. details as below:
1. server open a port and begin to listen.
2. client request and after connect to server, client begin to write to socket.
3. after server got the request, it will open a new thread to handle this connection. (this connection is a long connection which will not time out).
4. the server will keep reading until it got the end separator, then give a response to the client and continue to keep reading again.
5. after client get the response, it will send another request again.
I find if the client write the whole message (including the end separator) one time, the communication speed is good satisfactorily, the speed can reach to 50000 messages per minute. How ever, if the client write the bytes to socket in separated times, the speed cut down quickly, just almost 1400 messages per minute, it is 1/40 times compared with the original speed. I'm quite confused about it. Then I throw out my question in the stackoverflow and get a big help from some guys. The following is my server side:
public class ServerForHelp {
final static int BUFSIZE = 10240;
Socket socket;
String delimiter = "" + (char) 28 + (char) 13;
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9200);
System.out.println("begin to accept...");
while (true) {
Socket s = ss.accept();
Thread t = new Thread(new SocketThread1(s));
t.start();
}
}
public String readUntilDelimiter() throws Exception {
StringBuffer stringBuf = new StringBuffer();
InputStream stream = socket.getInputStream();
InputStreamReader reader = null;
reader = new InputStreamReader(stream);
char[] buf = new char[BUFSIZE];
while (true) {
int n = -1;
n = reader.read(buf, 0, BUFSIZE);
if (n == -1) {
return null; // it means the client has closed the connection, so return null.
} else if (n == 0) {
continue; // continue to read the data until got the delimiter from the socket.
}
stringBuf.append(buf, 0, n);
String s = stringBuf.toString();
int delimPos = s.indexOf(delimiter);
if (delimPos >= 0) {
// found the delimiter; return prefix of s up to separator and
// To make the thing simple, I have discarded the content after the delimiter.
String result = s.substring(0, delimPos);
sendTheResponse(socket);
return result;
}
}
}
private void sendTheResponse(Socket socket) throws IOException {
Writer writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("Hi, From server response");
writer.flush();
}
}
class SocketThread1 implements Runnable {
Socket socket;
public SocketThread1(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
ServerForHelp server = new ServerForHelp();
server.socket = socket;
while (true) {
try {
if (server.readUntilDelimiter() == null) // it means that the client has closed the connection, exist
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
It is a normal socket programming.
and the following is my client side:
public void execute() throws Exception{
int msgCnt = 0;
Socket socket = null;
byte[] bufBytes = new byte[512];
long start = 0;
final char START_MESSAGE = 0x0B;
final char END_MESSAGE = 0x1C;
final char END_OF_RECORD = 0x0D;//\r
String MESSAGE = "HELLO, TEST";
socket = new Socket("192.168.81.39", 9200);
OutputStream os = socket.getOutputStream();
InputStream is = socket.getInputStream();
while (System.currentTimeMillis() - start < 60000)
{
// If you send the total message at one time, the speed will be improved significantly
// FORMAT 1
StringBuffer buf = new StringBuffer();
buf.append(START_MESSAGE);
buf.append(MESSAGE);
buf.append(END_MESSAGE);
buf.append(END_OF_RECORD);
os.write(buf.toString().getBytes());
// FORMAT 1 END
//FORMAT 2
// os.write(START_MESSAGE);
// os.write(MESSAGES[port].getBytes());
// os.write(END_MESSAGE);
// os.write(END_OF_RECORD);
//FORMAT 2 END
os.flush();
is.read(bufBytes);
msgCnt++;
System.out.println(msgCnt);
}
System.out.println( msgCnt + " messages per minute");
}
If I use the "FORMAT 1", to send the message, the speed could reach to 50000 messages per minute, but If use "FORMAT 2", the speed is down to 1400 messages per minute.
And the following is the response I got from stackoverflow:
Multiple very short writes to a socket in rapid succession followed by a read can trigger a bad interaction between
Nagle's algorithm and TCP delayed acknowledgment; even if you disable Nagle's algorithm, you'll cause an entire packet to be sent per individual write call (with 40+ bytes of overhead, whether the write is one byte or a thousand).
Wrapping a BufferedOutputStream around the socket's output stream should give you performance similar to "FORMAT 1" (precisely because it holds things in a byte array until it fills or is flushed).
As
John Nagle explained on Slashdot:
The user-level solution is to avoid write-write-read sequences on sockets. write-read-write-read is fine. write-write-write is fine. But write-write-read is a killer. So, if you can, buffer up your little writes to TCP and send them all at once.
===end
With this answer, I'm more clear about the TCP socket now and the performance issue has been resolved too.
分享到:
相关推荐
Learn to plan a performance investigation in enterprise applications Build a performance troubleshooting strategy Design and implement high performing Java enterprise applications In Detail With the ...
Design and performance investigation of LDPC-coded upstream transmission systems in IM/DD OFDM-PONs
using five Java GUI capture and replay tools for GUI performance test automation. Besides confirming the severity of the previously known GUI element identification problem, we also describe a related...
TEMS 14.2更新说明 TEMS Investigation 14.2 Release Note
opti-scan+Investigation+7.4.3.0+-+Internal+until+2018.10.01
详细的介绍了TEMS INVESTIGATION的最新功能
TEMS_Investigation__7.1中文说明书
TEMS Investigation GSM 5.0 是前台路测软件,Deskcat 5.5 是后台分析软件。因为软件版本较新,无法使用万禾的数据转换功能转换到万禾的后台分析。 TEMS Investigation GSM 5.0 加密狗集成在测试手机里面,无须另外...
AS-IS_Investigation-SD_Module
Numerical Investigation of the Interaction of Counterflowing Jets and Supersonic Capsule Flows
TEMS Investig ation 使用说明.docx。 资源分享下载
It is numerically verified and experimentally demonstrated that circular (7,1) shows obvious superiority in the performance of the dynamic range of signal voltage peak-to-peak (vpp) value and bi
llc设计经典文章,建议反复读
for front end Dc-DC converter LLC converter
TEM与EDX方法在土壤矿物对Pb吸附方面的应用,王思源,卢升高,本研究采用透射电镜(TEM)和X射线能谱(EDX)研究两种土壤(潮软土和网纹湿老成土)中不同矿物对铅(Pb)的吸附,用选区电子衍射(SEAD
interface of llvm investigation, about ir, option, pragma,backend etc.
TEMS是目前世面上最全面的无线网络优化产品解决...TEMS Investigation 10.0 概述 TEMS Investigation 10.0的使用介绍 TEMS Investigation 10.0 Data Collection(前台) TEMS Investigation 10.0 Route Analysis(后台)
钙硼化合物的拉曼散射研究,韩宪越,于栋利,本文应用群伦和拉曼散射技术研究了CaB4化合物的晶格振动行为,群伦研究表明CaB4晶体的布里渊区Г点应存在四种拉曼激活振动模式。应�
Investigation on the group delay performance of microwave photonic filters is presented. Analysis and simulation results show symmetrical distribution on the delayed optical signals in the impulse ...
《Vision:A Computational Investigation into the Human Representation and Processing of Visual Information》,计算机视觉奠基之作