对于考试我必须制作同步多人游戏,要在服务器端练习,我决定在两个客户交换鼠标位置的处理中做一点草图。
这个想法是当两个客户端连接到服务器时,服务器产生一个带有两个连接的线程,在线程客户端发送他的数据到服务器和服务器将数据转到客户端,所以服务器是一个简单的桥为了客户。
这是Java服务器代码:
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ProvaServerGioco {
public final static int PORT = 31946;
public final static int MAXPARTITE = 50;
private Socket player1;
private Socket player2;
public final static char separatore = '\n';
public static final String INDIRIZZOHAMACHI = "25.166.111.50";
public static final String INDIRIZZOLAN = "192.168.1.65";
public void start() throws UnknownHostException {
ExecutorService pool = Executors.newFixedThreadPool(MAXPARTITE);
StringBuilder mouse=new StringBuilder();
InetAddress addr = InetAddress.getByName(INDIRIZZOHAMACHI);
try (ServerSocket server = new ServerSocket(PORT, 0, addr)) {
while (true) {
{
if (player1 == null) {
try {
player1 = server.accept();
System.out.println("Ryu");
Writer out = new OutputStreamWriter(
player1.getOutputStream());
out.write("in attesa di giocatore 2" + separatore);
out.flush();
} catch (IOException ex) {
player1.close();
player1 = null;
}
}
if (player2 == null) {
try {
player2 = server.accept();
System.out.println("Ken");
Writer out = new OutputStreamWriter(
player2.getOutputStream());
out.write("in attesa di giocatore 2" + separatore);
out.flush();
} catch (IOException ex) {
player2.close();
player2 = null;
}
}
if(!checkConnessione(player1))
player1=null;
if(!checkConnessione(player2))
player2=null;
if (player2 != null && player1 != null) {
pool.submit(new ThreadPartita(player1, player2));
player1 = null;
player2 = null;
}
}
}
} catch (IOException ex) {
System.err.println(ex);
}
}
private boolean checkConnessione(Socket player) {
if (player != null)
try {
Writer out = new OutputStreamWriter(player.getOutputStream());
out.write(separatore);
out.flush();
return true;
} catch (IOException ex) {
try {
player.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
return false;
}
public static void main(String[] args) {
ProvaServerGioco server = new ProvaServerGioco();
try {
server.start();
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
这是比赛的主题:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.net.Socket;
import java.util.concurrent.Callable;
public class ThreadPartita implements Callable<Void>{
private Socket player1;
private Socket player2;
private Writer player1Out;
private Writer player2Out;
private BufferedReader readerPlayer1;
private BufferedReader readerPlayer2;
private boolean finePartita=false;
public ThreadPartita(Socket player1,Socket player2)
{
this.player1=player1;
this.player2=player2;
}
@Override
public Void call() throws Exception {
notificaConnessione(player1);
notificaConnessione(player2);
player1Out=new OutputStreamWriter(
player1.getOutputStream());
player2Out=new OutputStreamWriter(
player2.getOutputStream());
readerPlayer1=new BufferedReader(new InputStreamReader(player1.getInputStream(), "ASCII"));
readerPlayer2=new BufferedReader(new InputStreamReader(player2.getInputStream(), "ASCII"));
String mousePlayer1="";
String mousePlayer2="";
while(true&&!finePartita)
{
mousePlayer2=readerPlayer2.readLine();
mousePlayer1=readerPlayer1.readLine();
player1Out.write(mousePlayer2+ProvaServerGioco.separatore);
player1Out.flush();
System.out.println(mousePlayer1);
System.out.println(readerPlayer2.ready());
player2Out.write(mousePlayer1+ProvaServerGioco.separatore);
player2Out.flush();
}
return null;
}
private void inviaMessaggio(Socket player,String messaggio)
{
try{
Writer out = new OutputStreamWriter(
player.getOutputStream());
out.write(messaggio);
out.flush();
}
catch(IOException ex)
{
System.out.println("partita annullata");
}
}
private void notificaConnessione(Socket player)
{
inviaMessaggio(player,"Sei connesso"+ProvaServerGioco.separatore);
}
}
此代码中的问题是当我从ThreadPartita中的player2读取数据时:
mousePlayer2=readerPlayer2.readLine();
在这一行中,程序冻结,如果我评论该行一切正常,并且player1正确地将他的数据发送到player2。
我肯定知道这是一个noob错误,但我不知道如何修复它因为我是服务器套接字的初学者(我正在研究o'Reilly的书“java network programming”天)。
我不知道是否有用,但这是客户端处理的代码:
import java.net.*;
import java.io.*;
import java.io.Writer;
StringBuilder mouse;
final static int PORTA=31946;
//final static int PORTA=13;
String mouseStringa;
String hamachiIP="127.0.0.1";
Socket socket;
Writer out;
BufferedReader reader;
void setup()
{
size(800,800);
try{
socket = new Socket(hamachiIP, PORTA);
socket.setSoTimeout(15000);
out=new OutputStreamWriter(
socket.getOutputStream());
InputStream in = socket.getInputStream();
mouse = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(in, "ASCII"));
mouseStringa=reader.readLine();
}
catch (IOException ex)
{
System.err.println(ex);
}
}
void draw()
{
background(255);
println(mouseStringa);
try{
mouse = new StringBuilder();
if(reader.ready())
{
String appoggio=reader.readLine();
if(appoggio.length()>0)
mouseStringa=reader.readLine();
}
String posizioniMouse=""+mouseX+';'+mouseY+'\n';
out.write(posizioniMouse);
out.flush();
}
catch (IOException ex)
{
System.err.println(ex);
}
frame.setTitle("fps: "+frameRate);
}
感谢您的关注!