gpt4 book ai didi

java - TCP 服务器疯狂 - 缓慢且合并的数据

转载 作者:行者123 更新时间:2023-12-01 23:20:41 25 4
gpt4 key购买 nike

我最近开始制作 2d java 游戏,现在我开始使用 TCP 服务器,尽管服务器运行速度非常慢(平均 2 秒),而且我不知道如何阻止输入流计量所有数据成一根弦。如果有人能够帮助我,我将不胜感激。

服务器代码:

package com.diedericksclan.main.network;

import java.io.*;
import java.net.*;
import java.util.ArrayList;

public class ServerThread extends Thread {

private ServerHandler server;
private ServerSocket dataSocket;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;
private int dedicated = 1024;
public int RAM = megabyte * dedicated;

private WriteData send;
private ReadData read;

public ServerThread(ServerHandler server, String serverIP, int ram, int backlog) throws Exception {
this.server = server;
this.dedicated = ram;
//System.out.println(serverIP);
String ip = "localhost";
int port = 2048;
if(serverIP.contains(":")) {
ip = serverIP.split(":")[0];
port = Integer.parseInt(serverIP.split(":")[1]);
} else {
ip = serverIP;
port = 2048;
}
//System.out.println("Makin' the server");
this.dataSocket = new ServerSocket(port, backlog, InetAddress.getByName(ip));
this.address = new InetSocketAddress(dataSocket.getInetAddress(), port);
this.send = new WriteData();
this.read = new ReadData();
//System.out.println("Makin' the data handlers");

//System.out.println("Server has been made, details: " + address.getAddress() + ":" + address.getPort());
}

public ServerThread(ServerHandler server, String ip) throws Exception {
this(server, ip, 1024, 0);
}

public void run() {
//System.out.println("made");
this.send.start();
this.read.start();
while(true) {
try {
socket = dataSocket.accept();
socket.setReceiveBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
} catch (IOException e) {
e.printStackTrace();
}
}
}


public void sendData(byte[] data, InetAddress IPaddress, int port) {
this.send.sendData(data, IPaddress, port);
}

public void serverShutdown() {
try {
this.dataSocket.close();
if(this.socket != null) this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public class WriteData extends Thread {
public WriteData() {}
public void sendData(byte[] data, InetAddress IPaddress, int port) {
try {
System.out.println("[" + System.currentTimeMillis() + "] Sending... " + new String(data));
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public class ReadData extends Thread {
public ReadData() {}
public void run() {
try {
this.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
byte[] data;
while(true) {
try {
data = new byte[megabyte];
socket.getInputStream().read(data);

System.out.println("[" + System.currentTimeMillis() + "] Server has read, " + new String(data) + ", details: " + socket.getLocalAddress().getHostName() + ":" + socket.getLocalPort());

server.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

客户端代码:

package com.diedericksclan.main.network;

import java.io.*;
import java.net.*;

public class ClientThread extends Thread {

private ClientHandler client;
private Socket socket;
private InetSocketAddress address;
private int megabyte = 1024 * 1024;

private WriteData send;
private ReadData read;

public ClientThread(ClientHandler client) {
this.client = client;
this.address = new InetSocketAddress("192.168.1.2", 2048);
socket = new Socket();
try {
socket.setSendBufferSize(megabyte);
socket.setSendBufferSize(megabyte);
socket.setTcpNoDelay(true);
socket.connect(address);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println("Made client");
this.send = new WriteData();
this.read = new ReadData();
//System.out.println("Client has been made, details: " + socket.getLocalAddress() + ":" + socket.getLocalPort());
}


public void run() {
//System.out.println("made");
this.send.start();
this.read.start();
}

public void sendData(byte[] data) {
this.send.sendData(data);
}

public void serverShutdown() {
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}

public class WriteData extends Thread {
public WriteData() {}
public void sendData(byte[] data) {
try {
//System.out.println("[" + System.currentTimeMillis() + "] Sending... " + new String(data) + " to: " + socket.getInetAddress() + ":" + socket.getPort());
socket.getOutputStream().write(data);
socket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public class ReadData extends Thread {
public ReadData() {}
public void run() {
byte[] data;
while(true) {
try {
data = new byte[megabyte];
socket.getInputStream().read(data);
System.out.println("[" + System.currentTimeMillis() + "] Server data recived, " + new String(data).trim());
client.parsePacket(data, socket.getInetAddress(), socket.getPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

我确实尝试通过在客户端和服务器中创建 2 个单独的线程来读取和写入数据来提高速度,但没有任何改进,

最佳答案

您遇到一些问题。

  • 您允许任意数量的线程同时写入同一个套接字。这使得开发协议(protocol)变得非常困难。
  • 您需要一个协议(protocol),以便了解消息的开始和结束位置。例如您先发送长度。
  • 您忽略读取了多少字节。最小值为 1,您可以一次获取任意数量的消息,最多可达缓冲区的大小。 TCP 是流协议(protocol),而不是消息协议(protocol)。

如果您在同一台计算机上有读取器和写入器进程,您应该能够将延迟控制在 10 微秒左右。 (0.000010 秒)

<小时/>

编辑这里是一个简单的例子

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;


public class PlainIOSample {
static final int RUNS = 1000000;

public static void main(String[] args) throws IOException {

ServerSocket ss = new ServerSocket(0);
DataSocket ds = new DataSocket(new Socket("localhost", ss.getLocalPort()));
DataSocket ds2 = new DataSocket(ss.accept());

long start = System.nanoTime();
for (int i = 0; i < RUNS; i++) {
// send a small message
ds.write(new byte[64]);
// receive the same message
byte[] bytes = ds2.read();
if (bytes.length != 64)
throw new AssertionError();
}
long time = System.nanoTime() - start;
System.out.printf("Average time to send/recv was %.1f micro-seconds%n",
time / RUNS / 1e3);
ds.close();
ds2.close();
}

static class DataSocket implements Closeable {
private final DataOutputStream dos;
private final DataInputStream dis;
private final Socket socket;

public DataSocket(Socket socket) throws IOException {
dos = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
dis = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
this.socket = socket;
}

public void write(byte[] message) throws IOException {
synchronized (dos) {
dos.writeInt(message.length);
dos.write(message);
dos.flush();
}
}

public byte[] read() throws IOException {
synchronized (dis) {
int length = dis.readInt();
byte[] bytes = new byte[length];
dis.readFully(bytes);
return bytes;
}
}

@Override
public void close() throws IOException {
socket.close();
}
}
}

打印

Average time to send/recv was 3.3 micro-seconds

关于java - TCP 服务器疯狂 - 缓慢且合并的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20678446/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com