2013-02-12 53 views
4
我有一点麻烦

多客户,现在我已经看过这个教程 http://docs.oracle.com/javase/tutorial/networking/sockets/clientServer.html 本教程为您提供了多个客户端可以连接到,当他们连接到他们被告知该服务器的服务器随着一个敲门工作,现在我明白如何传输数据,什么不是,但线程是如何工作的?服务器通过螺纹

我正在一个网络pong游戏中,服务器将持有这些职位并将它们传递给客户端,现在我有一个客户端连接到服务器,并且球位置传递给客户端,工作正常,有点跳动,但我确定一个带有.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(); 

我得到这个错误“无法转换无效主题” 如果任何人都可以照我的问题有些光这将是巨大的。

帆布

更新

我现在有自己的线程类

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是凝聚在一起字符串中的所有信息,现在如果我宣布在PLAYER1字符串我的乒乓服务器的顶部像这样

private static PongPlayerThread player1; 

and do th是当它是听

while(listen) 
    { 
     PongPlayerThread player1 = new PongPlayerThread(serverSocket.accept(), 0).start(); 
    } 

它给了我这个错误“无法从空转变为PongPlayerThread”如何解决这一行?

回答

0

你的数组声明中缺少对象类型

KKMultiServerThread multi[0] = new KKMultiServerThread(serverSocket.accept()).start(); 

何苦关系吗?除非线程需要彼此通信,否则让线程自由运行是可以的。就服务器而言,Run()方法定义套接字的整个生命周期。每个线程都有一个游戏状态的独立副本(只要你不使用静态),并且会在没有任何额外干预的情况下快乐地与客户端进行通信。

这是一个Java中的Socket/Thread库对你有利的情况,除非你有特定的需求,否则不要使它更复杂。

+0

确定这里还有另一个问题,当一个客户端连接第一个客户端需要能够控制屏幕右侧的蝙蝠时,第二个客户端需要控制屏幕的左侧蝙蝠,我怎么知道哪个客户端是哪一个? 此外,你给我的线说KKMultiServerThread不能解析为变量 – Canvas 2013-02-12 17:56:53

+0

你可以创建特定的线程实例像player1(左)和player2(右),并更改服务器只接受两个连接,然后再停止监听。然后玩家的代码有一个简单的标志,告诉它它应该是哪一边。 – 2013-02-12 17:59:33

+0

我会怎么做呢? – Canvas 2013-02-12 18:01:10

0

当客户端连接到服务器时。服务器通常会为该客户端专门创建一个新线程。以下是一些伪代码:

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,并且数据压缩尽量减少带宽,一次不会发送50GB的信息;如果你只需要几个字节的信息就可以发送。尝试发送不是字符串而是字节的位置信息。例如,您可以将位置X = 5Y = 0发送为50,并将第一个十进制数字解析为X,将第二个十进制数字解析为Y.

而不是在线程例程中传递客户端套接字,客户。由于Pong是两个玩家限制与两个客户的连接。0玩家1和1球员2.所以

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++; 
} 
+0

乒乓游戏需要先在TCP/IP然后UDP:D – Canvas 2013-02-12 17:57:25

+0

好吧,我会抓取UDP部分。 – 2013-02-12 17:58:11

+0

好吧,所以构造函数接受一个int为其clientID,但对于输入如何检查它的ID? new KKMultiServerThread(clientID).start(); // clientID的类型是int 但是我的构造函数被赋予了一个套接字?它应该采用socket和clientID吗? – Canvas 2013-02-12 18:08:14