在java中进行socketing时存在巨大的延迟
(更新代码) 我试图让客户端与服务器通信(我制作了简单的客户端-服务器应用程序,比如聊天室)。通信已创建,但存在巨大的延迟(我将坐标从客户端发送到服务器)。超过10秒(有时甚至更长)。有什么问题吗? 客户:在java中进行socketing时存在巨大的延迟,java,multithreading,sockets,delay,Java,Multithreading,Sockets,Delay,(更新代码) 我试图让客户端与服务器通信(我制作了简单的客户端-服务器应用程序,比如聊天室)。通信已创建,但存在巨大的延迟(我将坐标从客户端发送到服务器)。超过10秒(有时甚至更长)。有什么问题吗? 客户: public class GameComponent extends Canvas implements Runnable { private static final long serialVersionUID = 1L; private static final
public class GameComponent extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static final int WIDTH = 320;
private static final int HEIGHT = 240;
private static final int SCALE = 2;
private boolean running;
private JFrame frame;
Thread thread;
public static final int GRID_W = 16;
public static final int GRID_H = 16;
private Socket socket;
private DataInputStream reader;
private DataOutputStream writer;
private HashMap<Integer, OtherPlayer> oPlayers;
private ArrayList<OtherPlayer> opList;
private int maxID = 1;
private int ID;
Player player;
public GameComponent() {
//GUI code..
oPlayers = new HashMap<Integer, OtherPlayer>(); //Hash map to be able to get players by their ID's
opList = new ArrayList<OtherPlayer>(); //And an array list for easier drawing
setUpNetworking();
start();
}
public void start() {
if (running)
return;
running = true;
thread = new Thread(this);
player = new Player(GRID_W * 2, GRID_H * 2);
thread.start();
}
public void stop() {
if (!running)
return;
running = false;
}
public void run() { //The main loop, ticks 60 times every second
long lastTime = System.nanoTime();
double nsPerTick = 1000000000D / 60D;
int frames = 0;
int ticks = 0;
long lastTimer = System.currentTimeMillis();
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
boolean shouldRender = true;
while (delta >= 1) {
ticks++;
tick(delta);
delta -= 1;
shouldRender = true;
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (shouldRender) {
frames++;
render();
}
if (System.currentTimeMillis() - lastTimer >= 1000) {
lastTimer += 1000;
frames = 0;
ticks = 0;
}
}
}
private void tick(double delta) { //main logic
player.move();
try {
writer.writeInt(ID); //I send the player data here (id, x, y)
writer.writeInt(player.getX());
writer.writeInt(player.getY());
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
private void render(Graphics2D g2d) {
//rendering the stuff
for (OtherPlayer i : opList) { //drawing a black rectangle for every other player
g2d.fillRect(i.getX(), i.getY(), GRID_W, GRID_H);
}
}
private void render() {
//more rendering...
}
public static void main(String[] args) {
new GameComponent();
}
class TKeyListener implements KeyListener {
//movement methods...
}
private void setUpNetworking() { //This is where I make my message reader and data IO
try {
socket = new Socket("127.0.0.1", 5099);
reader = new DataInputStream(socket.getInputStream());
writer = new DataOutputStream(socket.getOutputStream());
Thread rT = new Thread(new msgReader());
rT.start();
} catch (Exception e) {
e.printStackTrace();
}
}
class msgReader implements Runnable { //where I read messages
public void run() {
try {
ID = reader.readInt(); //when I connect, I get an id from the server
while(true) { //my main loop
int oid = reader.readInt(); //get the read data id
int ox, oy;
ox = reader.readInt(); //get the read player's x and y
oy = reader.readInt();
if (oid != ID){ //If not reading myself
if (oPlayers.containsKey(oid)) { //If a player with this id exists
OtherPlayer op = (OtherPlayer) oPlayers.get(oid);
op.setX(ox); //set it's x, y
op.setY(oy);
} else { //if it doesn't exist, create him
OtherPlayer op = new OtherPlayer(ox, oy);
opList.add(op);
oPlayers.put(oid, op);
}
}
maxID = reader.readInt(); //Allways read the highest current id from server
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
公共类GameComponent扩展画布实现可运行{
私有静态最终长serialVersionUID=1L;
专用静态最终整数宽度=320;
专用静态最终内部高度=240;
专用静态最终整数刻度=2;
私有布尔运行;
私有JFrame;
螺纹;
公共静态最终整数网格W=16;
公共静态最终整数网格_H=16;
专用插座;
私有数据输入流读取器;
专用数据输出流编写器;
私有HashMap-oplayer;
私人ArrayList;
私有int maxID=1;
私有int-ID;
玩家;
公共游戏组件(){
//GUI代码。。
oPlayers=new HashMap();//能够通过ID获取玩家的哈希映射
opList=new ArrayList();//和一个数组列表,便于绘制
设置网络();
start();
}
公开作废开始(){
如果(正在运行)
返回;
运行=真;
线程=新线程(此);
玩家=新玩家(网格W*2,网格H*2);
thread.start();
}
公共停车场(){
如果(!正在运行)
返回;
运行=错误;
}
public void run(){//主循环,每秒滴答60次
long lastTime=System.nanoTime();
双nsPerTick=1000000000D/60D;
int帧=0;
int ticks=0;
long lastTimer=System.currentTimeMillis();
双增量=0;
(跑步时){
long now=System.nanoTime();
delta+=(现在-上次)/nsPerTick;
上次=现在;
布尔值shouldRender=true;
而(增量>=1){
ticks++;
蜱虫(δ);
delta-=1;
shouldRender=true;
}
试一试{
睡眠(2);
}捕捉(中断异常e){
e、 printStackTrace();
}
if(shouldRender){
frames++;
render();
}
如果(System.currentTimeMillis()-lastTimer>=1000){
lastTimer+=1000;
帧=0;
滴答声=0;
}
}
}
私有void tick(双增量){//主逻辑
player.move();
试一试{
writer.writeInt(ID);//我在这里发送播放器数据(ID,x,y)
writer.writeInt(player.getX());
writer.writeInt(player.getY());
writer.flush();
}捕获(IOE异常){
e、 printStackTrace();
}
}
专用空心渲染(Graphics2D g2d){
//渲染这些东西
对于(otherplayerI:opList){//为每个其他玩家绘制一个黑色矩形
g2d.fillRect(i.getX(),i.getY(),GRID_W,GRID_H);
}
}
私有void render(){
//更多渲染。。。
}
公共静态void main(字符串[]args){
新游戏组件();
}
类TKeyListener实现KeyListener{
//移动方法。。。
}
private void setUpNetworking(){//这是我制作消息读取器和数据IO的地方
试一试{
插座=新插座(“127.0.0.1”,5099);
reader=newdataInputStream(socket.getInputStream());
writer=newdataoutputstream(socket.getOutputStream());
线程rT=新线程(新的msgReader());
rT.start();
}捕获(例外e){
e、 printStackTrace();
}
}
类msgReader实现可运行的{//,我在其中读取消息
公开募捐{
试一试{
ID=reader.readInt();//当我连接时,我从服务器获得一个ID
while(true){//我的主循环
int oid=reader.readInt();//获取读取的数据id
int-ox,oy;
ox=reader.readInt();//获取读取的播放器的x和y
oy=reader.readInt();
如果(oid!=ID){//如果不读我自己
if(oPlayers.containsKey(oid)){//如果存在具有此id的玩家
OtherPlayer op=(OtherPlayer)oPlayers.get(oid);
op.setX(ox);//设置为x,y
op.setY(oy);
}否则{//如果它不存在,就创造他
OtherPlayer op=新的OtherPlayer(公牛,oy);
opList.add(op);
oPlayers.put(oid,op);
}
}
maxID=reader.readInt();//始终从服务器读取当前最高id
}
}捕获(例外情况除外){
例如printStackTrace();
}
}
}
}
和服务器:
public class ServerBase {
ServerSocket serverSocket;
ArrayList<DataOutputStream> clients;
private int id = 1;
SyncSend ss = new SyncSend();
class ClientHandler implements Runnable {
private Socket soc;
private DataInputStream reader;
private int x;
private int y;
private int id;
private boolean run = true;
public ClientHandler(Socket s) {
soc = s;
try {
reader = new DataInputStream(soc.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
while (run) {
id = reader.readInt();
x = reader.readInt();
y = reader.readInt();
if (id == 2)
System.out.println("x: " + x + " y: " + y);
int[] tmb = {id, x, y};
ss.sendEveryone(tmb);
}
} catch (Exception e) {
run = false;
clients.remove(this);
}
}
}
class SyncSend {
public synchronized void sendEveryone(int[] a) throws SocketException {
ArrayList<DataOutputStream> cl = (ArrayList<DataOutputStream>) clients.clone();
Iterator<DataOutputStream> it = cl.iterator();
while(it.hasNext()){
try {
DataOutputStream writer = (DataOutputStream) it.next();
writer.writeInt(a[0]);
writer.writeInt(a[1]);
writer.writeInt(a[2]);
writer.writeInt(id-1);
writer.flush();
} catch (Exception ex) {
throw new SocketException();
}
}
}
}
public void init() {
clients = new ArrayList<DataOutputStream>();
try {
serverSocket = new ServerSocket(5099);
while(true) {
Socket clientSocket = serverSocket.accept();
DataOutputStream clientWriter = new DataOutputStream(clientSocket.getOutputStream());
clients.add(clientWriter);
clientWriter.writeInt(id);
id++;
Thread t = new Thread(new ClientHandler(clientSocket));
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new ServerBase().init();
}
}
公共类ServerBase{
服务器套接字服务器套接字;
ArrayList客户;
私有int id=1;
SyncSend ss=新的SyncSend();
类ClientHandler实现Runnable{
专用插座soc;
私有数据输入流读取器;
私人INTX;
私营企业;
私有int-id;
私有布尔运行=true;
公共ClientHandler(插座s){
soc=s;
试一试{
reader=newdataInputStream(soc.getInputStream());
}捕获(IOE异常){
e、 printStackTrace();
}
}
公开募捐{
试试{
while(运行){
id=reader.readInt();