4

少し問題があります。このチュートリアルを見てきました 。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をスレッドに変換できません」というエラーが表示されます。誰かが私の問題に光を当てることができれば、それは素晴らしいことです。

キャンバス

アップデート

私は今、自分のスレッドクラスを持っています

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に変換できません」というエラーが表示されます。これを修正するにはどうすればよいですか?

4

2 に答える 2

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のクライアントに独自のスレッドを持たせたくありません。あなたのマシンがそれをすべて処理し、それでも実行できる場合を除きます。TCPの代わりにUDPを使用し、データ圧縮は帯域幅を最小限に抑えようとします。一度に50GBの情報を送信しないでください。必要なのは、送信する情報の数バイトだけです。位置の情報を文字列ではなくバイト単位で送信してみてください。たとえば、位置X = 5Y = 0を50として送信し、最初の10進数をXとして、2番目の10進数をYとして解析できます。

スレッドルーチン内でクライアントソケットを渡す代わりに、クライアントの一意の識別子を渡します。Pongは2人のプレーヤーであるため、接続を2つのクライアントに制限します。プレーヤー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++;
}
于 2013-02-12T17:51:47.627 に答える
0

配列宣言にオブジェクトタイプがありません

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

なぜわざわざ?スレッドが相互に通信する必要がない限り、スレッドを自由に実行させることは問題ありません。Run()メソッドは、サーバーに関する限り、ソケットの存続期間全体を定義します。各スレッドには、ゲームの状態の個別のコピーがあり(統計を使用しない限り)、余分な介入なしにクライアントとうまく通信します。

これは、JavaのSocket / Threadライブラリが非常に有利な場合です。特別な必要がない限り、複雑にしないでください。

于 2013-02-12T17:55:32.080 に答える