我遇到了一些麻烦,现在我已经看了本教程http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html本教程为您提供了一个多个客户端可以连接的服务器,当他们连接到服务器时,他们被告知要执行敲门作业,现在我了解了如何传输数据以及不传输什么,但线程是如何工作的?
我正在做一个网络乒乓球游戏,服务器会保持位置并将其传递给客户端,现在我有一个客户端连接到服务器,球的位置传递给客户端。工作正常,有点跳跃,但我相信带有.sleep的线程会有帮助。但不管怎样,我的问题是,我如何才能让我的客户成为一个线程?我该如何储存它们?
例如,这里是敲敲服务器多线程类
package knockKnockServer;
import java.net.*;
import java.io.*;
public class KKMultiServerThread extends Thread {
private Socket socket = null;
public KKMultiServerThread(Socket socket) {
super("KKMultiServerThread");
this.socket = socket;
}
public void run() {
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();
outputLine = kkp.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye"))
break;
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在服务器中,我们有
package knockKnockServer;
import java.net.*;
import java.io.*;
public class MultiKKServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(-1);
}
while (listening)
new KKMultiServerThread(serverSocket.accept()).start();
serverSocket.close();
}
}
现在看看服务器,它会在每个连接上创建一个新的KKMultiServerThread,但我如何存储它们?我可以制作一个KKMultiServerThread数组吗?我尝试制作一个KKMultiServerThread数组当我尝试这条线路时
multi[0] = new KKMultiServerThread(serverSocket.accept()).start();
我得到这个错误"无法将void转换为Thread"如果有人能揭露我的问题,那就太好了。
画布
更新
我现在有了自己的线程类
package Pong;
import java.net.*;
import java.io.*;
public class PongPlayerThread extends Thread
{
private Socket socket = null;
private String pongData = "";
public PongPlayerThread(Socket socket, int id)
{
super("PongPlayerThread");
this.socket = socket;
}
public void passData(String data)
{
pongData = data;
}
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
while(true)
{
out.println(pongData);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
pongData是一个字符串,它将所有信息保存在一个字符串中,现在如果我像一样在pong服务器的顶部声明一个player1
private static PongPlayerThread player1;
并且当它正在收听时执行这一行
while(listen)
{
PongPlayerThread player1 = new PongPlayerThread(serverSocket.accept(), 0).start();
}
它给了我一个错误"无法从void转换为PongPlayerThread",我该如何解决这个问题?
您的数组声明缺少对象类型
KKMultiServerThread multi[0] = new KKMultiServerThread(serverSocket.accept()).start();
为什么要麻烦呢?除非线程需要相互通信,否则让线程自由运行是可以的。run()方法定义了套接字的整个生存期。每个线程都有一个单独的游戏状态副本(只要你不使用静态),并且会很高兴地与客户端通信,而不需要任何额外的干预。
在这种情况下,Java中的Socket/Thread库帮了你很大的忙,除非你有特定的需求,否则不要让它变得更复杂。
当客户端连接到服务器时。服务器通常会专门为该客户端创建一个新线程。这里有一些伪代码:
WHILE SERVER IS RUNNING
SERVER WAITS FOR A CLIENT TO CONNECT
SERVER ACCEPTS THE CLIENT IF THERE IS ENOUGH MEMORY TO CREATE A NEW THREAD
SERVER CREATES A NEW THREAD ROUTINE FOR THE CLIENT PASSING THE CLIENT INFORMATION TO THE THREAD
SERVER CONTINUES TO LISTEN WHILE EACH THREAD IS SPECIFICALLY TAILORED FOR THE CLIENTS
REPEAT
您询问需要采取哪些步骤来减少滞后?首先,设置允许的最大连接数。您不希望5000个客户端拥有自己的线程。除非你的机器能处理所有这些并且还能运行。使用UDP而不是TCP,数据压缩尽量减少带宽——不要一次发送50 GB的信息;如果您只需要发送几个字节的信息。尝试不以字符串形式而是以字节形式发送位置信息。例如,您可以将位置X=5Y=0发送为50,并将第一个十进制数字解析为X,将第二个十进制数字分析为Y。
不是在线程例程内传递客户端套接字,而是为客户端传递一个唯一标识符。由于Pong是两个玩家,因此将连接限制为两个客户端。玩家1为0,玩家2为1。所以
new KKMultiServerThread(clientID).start(); // clientID is of type int
编辑:
int id = 0;
while(serverIsRunning)
{
Client client = server.accept();
if (id > 2) client.Close(); // Do not accept.
Thread.New(id).Start();
id++;
}