最近、Java ソケットを使用しているときに Tcp のパフォーマンスについて混乱しています。実際、Java コードは非常に単純です。以下のように詳細:
- サーバーはポートを開き、リッスンを開始します。
- クライアント要求とサーバーへの接続後、クライアントはソケットへの書き込みを開始します。
- サーバーはリクエストを受け取った後、この接続を処理するために新しいスレッドを開きます。(この接続はタイムアウトしない長い接続です)。
- サーバーはエンドセパレーターを取得するまで読み取りを続け、クライアントに応答を返し、再度読み取りを続けます。
- クライアントが応答を受け取った後、別の要求を再度送信します。
クライアントがメッセージ全体 (エンド セパレータを含む) を 1 回書き込むと、通信速度は十分に良好で、速度は毎分 50000 メッセージに達することがわかります。ただし、クライアントがバイトを別々の時間にソケットに書き込むと、速度が急速に低下し、1 分あたり約 1400 メッセージに過ぎず、元の速度と比較して 1/40 倍になります。私はそれについてかなり混乱しています。誰か手を貸してくれませんか?どんなコメントでも大歓迎です!
私のシミュレートされたサーバー側は次のとおりです。
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();
}
}
}
}
通常のソケットプログラミングです。
以下は私のクライアント側です:
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");
}
メッセージの送信に「FORMAT 1」を使用すると、速度は毎分 50000 メッセージに達する可能性がありますが、「FORMAT 2」を使用すると、速度は毎分 1400 メッセージに低下します。理由がはっきりしているのは誰ですか?
できる限り詳細に説明しようとしていますが、どんな助けでも大歓迎です。