目前我有一个在Android上运行的Java UDP服务器,服务器在端口上有一个datagramSocket,它首先只是监听客户端连接,客户端将在同一端口上创建一个新的datagramSocket,并发送一个数据包请求连接,一旦服务器收到这个,它会使用IP发送消息,然后只发送一个带有块位置的消息包,而客户端也发送回它自己的块位置,
信息,该应用程序允许多个用户连接到一个主机,该主机将接收客户端的所有位置然后将它们广播出去,还有其他方法可以做到,但我想这样做以进行研究。
但无论如何,问题在于,我的应用程序有望处理 8 个用户,因为该应用程序适用于 wifihotspot。我将如何允许多个客户端连接、发送数据和接收数据?我已经有了允许一个客户端连接的代码,主机将向该客户端发送数据,但是如果我尝试连接另一个客户端,我会收到错误,这是我的服务器和客户端代码
PS那里可能有一些调试代码,因为我需要清除它。
服务器代码
package com.example.gelorph_v1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Enumeration;
import org.apache.http.conn.util.InetAddressUtils;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
public class gameServer extends Thread {
/**
* Sets up a server for Android applciation
*/
private static final String TAG = "GameServer";
private DatagramSocket socket;
private int port = 50000;
private int players = 0;
private ArrayList<gameObject> assets = new ArrayList();
private ArrayList<InetAddress> address = new ArrayList();
private boolean wait = false;
private Context contextHolder = null;
//Make an array, this array will hold all the positions
//the clients sent to it,
//using the ID number, it will store it in a array block
//and the "host" can just return it and use that
public gameServer( Context context ) throws IOException
{
contextHolder = context;
socket = new DatagramSocket( port );
Log.d(TAG, "Server was setup");
}
public DatagramSocket rtnSocket(){ return socket; }
private String getLocalIPAddress()
{
try
{
for (Enumeration<NetworkInterface> nis = NetworkInterface.getNetworkInterfaces(); nis.hasMoreElements();)
{
NetworkInterface ni = nis.nextElement();
Log.v(TAG, "NetworkInterface = " + ni.getDisplayName());
for (Enumeration<InetAddress> ips = ni.getInetAddresses(); ips.hasMoreElements();)
{
InetAddress ip = ips.nextElement();
String s = ip.getHostAddress();
Log.v(TAG, "InetAddress = " + s);
if (!ip.isLoopbackAddress())
{
if(InetAddressUtils.isIPv4Address(s)) return s;
}
}
}
}
catch (SocketException e)
{
Log.e(TAG,"getLocalIPAddress()", e);
}
return null;
}
public void passClient( gameObject clientTemp )
{
assets.add( clientTemp );
}
protected void doInBackground()
{
}
@Override
public void run() {
InetAddress client = null;
boolean run = true;
String data = "";
DatagramPacket packet = null;
while( run )
{
if( data.equalsIgnoreCase( "" ) )
{
/*Log.d(TAG, "waiting for clients");
String msg = "waiting";
int msgLength = msg.length();
byte[] message = msg.getBytes();
DatagramPacket p = new DatagramPacket( message, msgLength, client, port );
try
{
socket.send( p );
}
catch (IOException e2)
{
Log.d(TAG, "Error with sending");
e2.printStackTrace();
}*/
}
//Send some data
if( data.equalsIgnoreCase( "connect" ) && wait == true )
{
Log.d(TAG, "ID send :" + packet.getAddress());
address.add( packet.getAddress() );
players += 1;
String msg = String.valueOf( players );
int msgLength = msg.length();
byte[] message = msg.getBytes();
DatagramPacket p = new DatagramPacket( message, msgLength, packet.getAddress(), port );
try
{
socket.send( p );
wait = false;
}
catch (IOException e2)
{
Log.d(TAG, "Error with sending");
e2.printStackTrace();
data = "";
}
}
//if( /*data.equalsIgnoreCase( "position" )*/ address.size() > 0 )
//{
//Create for loop to create the string
String msg = "";
msg = players + "#";
for(int i = 0; i < players; i++)
{
msg += + i + ":" + assets.get(i).returnPosX() + ":" + assets.get(i).returnPosY() + ":";
}
//msg = String.valueOf(
// players + ":" +
// "1:" + assets.get(0).returnPosX() + ":" + assets.get(0).returnPosY() );
int msgLength = msg.length();
byte[] message = msg.getBytes();
for(int i = 0; i < address.size() ; i++)
{
DatagramPacket p = new DatagramPacket( message, msgLength, address.get(i), port );
try
{
socket.send( p );
}
catch (IOException e2)
{
Log.d(TAG, "Error with sending");
e2.printStackTrace();
}
}
//Log.d(TAG, "Data sent is:" + msg);
//}
data = " ";
//Receive some data
if( wait == false )
{
byte[] buf = new byte[256];
packet = new DatagramPacket( buf, buf.length );
try
{
socket.receive( packet );
wait = true;
}
catch (IOException e)
{
Log.d(TAG, "Error with receiving data");
e.printStackTrace();
}
data = new String( buf, 0, packet.getLength() );
Log.d(TAG, "Data received from :" + packet.getAddress() + ", holds this value: " + data);
//Upset each asset with the data sent
}
//Log.d(TAG, "Data received was :" + data);
try
{
this.sleep( 25 );
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
Log.d(TAG, "Error with trying to sleep");
e.printStackTrace();
}
}
Log.d(TAG, "Error with while run value");
}
public int returnPlayers(){ return players; }
}
客户端代码
package com.example.gelorph_v1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.net.DhcpInfo;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.util.Log;
public class gameClient extends Thread {
private static final String TAG = "gameClient";
private gameServer server;
private boolean rdyForPlay = false;
private gameObject[] assets = new gameObject[8];
private int ID = 0;
private int port = 50000;
private InetAddress address;
private maths cal = new maths();
private Context contextHolder;
private boolean host = false;
private DatagramSocket socket = null;
private int totalPlayers = 0;
public gameClient( boolean serverTag, Context context )
{
if( serverTag == true)
{
host = true;
try
{
contextHolder = context;
server = new gameServer( contextHolder );
this.start();
}
catch (IOException e)
{
Log.d(TAG, "Could not start server");
e.printStackTrace();
}
}
else
{
contextHolder = context;
connectToServer();
this.start();
}
}
public void connectToServer()
{
//Send a connect message to the server
try {
socket = new DatagramSocket( port );
byte[] bufer = new byte[256];
String msg = "connect";
int msgLength = msg.length();
bufer = msg.getBytes();
InetAddress address;
address = InetAddress.getByName("192.168.1.59");
DatagramPacket p = new DatagramPacket( bufer, bufer.length , address, port );
socket.send( p );
} catch (UnknownHostException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Receive the message back
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket( buf, buf.length );
try
{
socket.receive( packet );
}
catch (IOException e)
{
Log.d(TAG, "Error with receiving data");
e.printStackTrace();
}
String data = new String( buf, 0, packet.getLength() );
ID = Integer.parseInt( data );
setUpClient();
Log.d(TAG, "Data received was :" + ID);
}
public void setUpClient()
{
gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.player), 250, 300);
assets[ID] = temp;
if( host == true )
{
server.passClient( temp );
}
}
public void sendTouchEvent(float xSet, float ySet)
{
assets[ID].setPosition( xSet, ySet );
}
@Override
public void run()
{
if( host == true ) { setUpClient(); server.start(); }
rdyForPlay = true;
boolean run = true;
boolean setupPlayer = false;
while( run )
{
//Tell the server to give position of players
//if( setupPlayer == true )
//{
// setUpClient();
// setupPlayer = false;
//}
if( host == false )
{
try {
if(socket == null)
{
socket = new DatagramSocket( port );
}
byte[] bufer = new byte[256];
//String msg = "position";
String msg = ID +":"+ assets[ID].returnPosX() +":"+ assets[ID].returnPosY();
int msgLength = msg.length();
bufer = msg.getBytes();
InetAddress address;
address = InetAddress.getByName("192.168.1.59");
DatagramPacket p = new DatagramPacket( bufer, bufer.length , address, port );
socket.send( p );
} catch (UnknownHostException e2) {
// TODO Auto-generated catch block
Log.d(TAG, "Error with unknown host");
e2.printStackTrace();
} catch (SocketException e) {
// TODO Auto-generated catch block
Log.d(TAG, "Error with socket");
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d(TAG, "Error with sending/receiving data");
e.printStackTrace();
}
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket( buf, buf.length );
try
{
socket.receive( packet );
}
catch (IOException e)
{
Log.d(TAG, "Error with receiving data");
e.printStackTrace();
}
String data = new String( buf, 0, packet.getLength() );
//Split the string up
String[] dataArray = data.split("#");
int newTotalPlayers = Integer.parseInt( dataArray[0] );
if( newTotalPlayers != totalPlayers )
{
Log.d(TAG," what is total amount of players:" + newTotalPlayers);
if( newTotalPlayers == 1 )
{
newPlayer( 0 );
totalPlayers = newTotalPlayers;
}
else
{
newPlayer( newTotalPlayers );
totalPlayers = newTotalPlayers;
}
//if( ID == 0 && host == false)
//{
// ID = newTotalPlayers;
// setupPlayer = true;
//}
}
//Do a for loop to go through dataArray
for( int i = 0; i < totalPlayers; i++)
{
String[] pos = dataArray[(i + 1)].split(":");
if( Integer.parseInt( pos[(i*3)] ) == ID )
{
Log.d(TAG, "Do nothing please");
}
else
{
assets[i].setPosition( Integer.parseInt( pos[(i*3) + 1] ), Integer.parseInt( pos[(i*3) + 2] ) );
}
}
}
//host
if( host == true )
{
/*if( server.returnPlayers() != totalPlayers )
{
Log.d(TAG," what is total amount of players:" + server.returnPlayers());
newPlayer( server.returnPlayers() );
totalPlayers = server.returnPlayers();
//if( ID == 0 && host == false)
//{
// ID = newTotalPlayers;
// setupPlayer = true;
//}
}*/
}
}
Log.d(TAG, "Error with run value");
}
private void newPlayer( int idOfNewPlayer )
{
gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.new_player), 250, 300);
assets[ idOfNewPlayer ] = temp;
}
private void updateAssets()
{
}
public gameObject[] rtnAssets(){ return assets; }
public int rtnID(){ return ID; }
public boolean rtnRdy(){ return rdyForPlay; }
public gameServer rtnServer(){ return server; }
public boolean rtnHost(){ return host; }
public void stopServers()
{
socket.close();
server.rtnSocket().close();
}
}
不要太担心当客户加入时会创建一个新块,我只是想弄清楚允许多个用户的最佳方式是什么?最重要的是如何?如果有人能指出我正确的方向,或者给出一些简单的示例代码,那就太好了。