Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/209.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java UDP支持多个连接到同一端口,发送和接收_Java_Android_Sockets_Networking_Udp - Fatal编程技术网

Java UDP支持多个连接到同一端口,发送和接收

Java UDP支持多个连接到同一端口,发送和接收,java,android,sockets,networking,udp,Java,Android,Sockets,Networking,Udp,目前,我有一个服务器,它允许客户端通过发送消息“connect”连接到它,当服务器收到此消息时,它接收InetAddress,然后使用该InetAddress向客户端发送数据,一旦客户端连接并收到其ID号,它会不断向UDP套接字发送数据,以便更新其位置,现在当新客户端想要连接时,它会发送消息“connect”,但新客户端很少会连接,现在发生的情况是,已连接的客户端使host.receive函数忙,所以当新客户端连接时,幸运的是,如果当前连接的客户端没有跳转,那么客户端只剩下一个空白屏幕 我需要的

目前,我有一个服务器,它允许客户端通过发送消息“connect”连接到它,当服务器收到此消息时,它接收InetAddress,然后使用该InetAddress向客户端发送数据,一旦客户端连接并收到其ID号,它会不断向UDP套接字发送数据,以便更新其位置,现在当新客户端想要连接时,它会发送消息“connect”,但新客户端很少会连接,现在发生的情况是,已连接的客户端使host.receive函数忙,所以当新客户端连接时,幸运的是,如果当前连接的客户端没有跳转,那么客户端只剩下一个空白屏幕

我需要的帮助是,如何支持使用同一端口的UDP套接字上的多个客户端? 所有将连接到服务器的客户端都位于同一路由器上

这是整个服务器代码

public class gameServer /*extends Thread*/ extends AsyncTask<String, String, String>{

/**
 * 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 String[] positions = new String[8];
private ArrayList<InetAddress> addresses = 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
{
    //Here we take in the clients block,
    //this will be assets[0];
    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 getClientPosition(int xPos, int yPos)
{
    positions[0] = xPos + ":" + yPos;
}

@Override
protected String doInBackground(String... params) {
    InetAddress client = null;
    boolean run = true;
    String data = "";
    DatagramPacket packet = null;
    boolean position = false;
    while( run )
    {
        if( data.equalsIgnoreCase( "" ) )
        {

        }

        //Send some data
        if( data.equalsIgnoreCase( "connect" ) && wait == true )
        {
            Log.d(TAG, "Someone wants to connect");
            //Increase the total players by 1
            players = players + 1;
            //Notify to the host (client) something has change
            //notify client
            //Send a message to the client with the ID
            byte[] bufer = new byte[256];
            //Send a message "connect" to the host
            String msg = Integer.toString( players );
            int msgLength = msg.length();
            bufer = msg.getBytes();
            InetAddress address;
            //Default ip address of the host
            //Take the address from the packet
            addresses.add( packet.getAddress() );
            Log.d(TAG, "Address is " + addresses.get( addresses.size() - 1 ) );
            address = addresses.get( addresses.size() - 1 );
            DatagramPacket p = new DatagramPacket( bufer, bufer.length , address, port );
            //Send packet
            try 
            {
                socket.send( p );
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }

            wait = false;
        }

        if( wait == true && position == true )
        {
            position = false;
            wait = false;
        }

        for(int i = 0;i < positions.length; i++)
        {
            if(positions[i] != null)
            {
            //Log.d(TAG, "X and Y position of asset:"+i+", is:"+ positions[i]);
            }
        }

        //Needs to try and reteive data...
        if( wait == false )
        {
            //Log.d(TAG, "Waiting to retreive data");
            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);
            String[] dataStrings = data.split(":");
            if( dataStrings[0].equalsIgnoreCase( "position" ) )
            {
                position = true;
            }
        }



        //Log.d(TAG, "Data received was :" + data);

        /*try 
        {
            Thread.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");
    return "finished";
}

public int returnPlayers(){ return players; }
}
公共类gameServer/*扩展线程*/扩展异步任务{
/**
*为Android应用程序设置服务器
*/
私有静态最终字符串TAG=“GameServer”;
专用DatagramSocket套接字;
专用int端口=50000;
私人整数玩家=0;
私有字符串[]位置=新字符串[8];
私有ArrayList地址=新ArrayList();
私有布尔等待=false;
私有上下文contextHolder=null;
//制作一个数组,此数组将保留所有位置
//发送给它的客户,
//使用ID号,它将其存储在数组块中
//而“主机”只需返回它并使用它
公共游戏服务器(上下文)引发IOException
{
//在这里,我们考虑客户区,
//这将是资产[0];
contextHolder=上下文;
套接字=新的DatagramSocket(端口);
Log.d(标记“服务器已设置”);
}
公共DatagramSocket rtnSocket(){return socket;}
私有字符串getLocalIPAddress()
{
尝试
{
对于(枚举nis=NetworkInterface.getNetworkInterfaces();nis.hasMoreElements();)
{
NetworkInterface ni=nis.nextElement();
Log.v(标记“NetworkInterface=“+ni.getDisplayName());
对于(枚举ips=ni.getInetAddresses();ips.hasMoreElements();)
{
InetAddress ip=ips.nextElement();
字符串s=ip.getHostAddress();
Log.v(标签,“InetAddress=“+s”);
如果(!ip.isLoopbackAddress())
{
if(InetAddressUtils.isIPv4Address)返回s;
}
}
}
}
捕获(SocketException e)
{
Log.e(标记“getLocalIPAddress()”,e);
}
返回null;
}
public void getClientPosition(int xPos,int yPos)
{
位置[0]=xPos+“:”+YPO;
}
@凌驾
受保护的字符串doInBackground(字符串…参数){
InetAddress客户端=null;
布尔运行=真;
字符串数据=”;
DatagramPacket数据包=null;
布尔位置=假;
while(运行)
{
if(data.equalsIgnoreCase(“”)
{
}
//发送一些数据
if(data.equalsIgnoreCase(“connect”)和&wait==true)
{
Log.d(标记“某人想要连接”);
//增加玩家总数1
玩家=玩家+1;
//向主机(客户端)通知发生了更改
//通知客户
//将带有ID的消息发送到客户端
字节[]bufer=新字节[256];
//向主机发送消息“连接”
字符串msg=Integer.toString(玩家);
int msgLength=msg.length();
bufer=msg.getBytes();
地址;
//主机的默认ip地址
//从包中取出地址
address.add(packet.getAddress());
Log.d(标记“Address is”+addresses.get(addresses.size()-1));
address=addresses.get(addresses.size()-1);
DatagramPacket p=新的DatagramPacket(bufer,bufer.length,address,port);
//发送数据包
尝试
{
socket.send(p);
} 
捕获(IOE异常)
{
e、 printStackTrace();
}
等待=错误;
}
if(wait==true&&position==true)
{
位置=假;
等待=错误;
}
对于(int i=0;ipublic class gameClient extends AsyncTask<String, String, String> 
{

//Variables
private static final String TAG = "gameClient";
private gameServer server;
private boolean rdyForPlay = false;
//Holds all of the over clients blocks
private gameObject[] assets = new gameObject[8];
private int ID = 0;
private int port = 50000;
private Context contextHolder;
//If this client is the host
private boolean host = false;
private DatagramSocket socket = null;
//How many clients are connected to the server
private int totalPlayers = 0;

//Constructor for gameclient
public gameClient( boolean serverTag, Context context )
{
    host = serverTag;
    //Client is host
    if( host == true)
    {
        host = true;
        try 
        {
            //Start the server
            contextHolder = context;
            server = new gameServer( contextHolder );
            this.execute();
        } 
        catch (IOException e) 
        {
            //Error
            Log.d(TAG, "Could not start server");
            e.printStackTrace();
        }
    }
    //Client is not host
    else
    {
        //Connect to the host
        contextHolder = context;
        this.execute();
    }
}

//Connect to the host, to receive and send data to
public void connectToServer()
{
    //Send a connect message to the server
    try {
        //Create a socket
        socket = new DatagramSocket( port );
        byte[] bufer = new byte[256];
        //Send a message "connect" to the host
        String msg = "connect";
        int msgLength = msg.length();
        bufer = msg.getBytes();
        InetAddress address;
        //Default ip address of the host
        address = InetAddress.getByName("192.168.1.59");
        DatagramPacket p = new DatagramPacket( bufer, bufer.length , address, port );
        //Send packet
        socket.send( p );

    } catch (UnknownHostException e2) {
        Log.d(TAG, "Unknown host");
        e2.printStackTrace();
    } catch (SocketException e) {
        Log.d(TAG, "Socket problem");
        e.printStackTrace();
    } catch (IOException e) {
        Log.d(TAG, "I/O problem");
        e.printStackTrace();
    }

    //Receive the message back
    byte[] buf = new byte[256];
    DatagramPacket packet = new DatagramPacket( buf, buf.length );
    //Try to receive a packet from the server
    try 
    {
        Log.d(TAG, "Waiting for data");
        socket.receive( packet );
    } 
    //Error
    catch (IOException e) 
    {
        Log.d(TAG, "Error with receiving data");
        e.printStackTrace();
    }

    //Convert the packet to a string
    String data = new String( buf, 0, packet.getLength() );

    //Use the string to find out what ID this client is
    ID = Integer.parseInt( data );
    //Setup the client game
    setUpClient();
}

//Setup the client game/screen
public void setUpClient()
{
    //Setup the client using the ID that was given by the host
    Log.d(TAG, "ID is : " + ID);
    gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.player), 250, 300);
    assets[ID] = temp;
    for(int i = 0; i < ID; i++)
    {
        temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.new_player), 50*i, 50*i);
        assets[i] = temp;
    }

    //If this client is the host, then pass the client to the server for easy access
    if( host == true )
    {
    server.getClientPosition( assets[ID].returnPosX(), assets[ID].returnPosY() );
    }
}

//When the screen is touched
public void sendTouchEvent(float xSet, float ySet)
{
    assets[ID].setPosition( xSet, ySet );
}

@Override
//Keep the game updated
protected String doInBackground(String... params)
{
    //Connect to the server
    if( host == false ){ while(ID == 0) { Log.d( TAG, "Client will connect to server" ); connectToServer(); } }
    //If the client is host, then start the server thread
    if( host == true ) { setUpClient(); server.execute(); }
    //game us now ready to be played
    rdyForPlay = true;
    boolean run = true;
    boolean setupPlayer = false;

    while( run )
    {
        int players = 0;
        //Tell the server to give position of players
        //if( setupPlayer == true )
        //{
        //  setUpClient();
        //  setupPlayer = false;
        //}
        if( host == true )
        {
            server.getClientPosition( assets[ID].returnPosX(), assets[ID].returnPosY() );
            int newPlayers = server.returnPlayers();
            if( players != newPlayers )
            {
                for(int i = players; i < newPlayers; i++)
                {
                    i = i+1;
                    gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.new_player), 50*i, 50*i);
                    assets[i] = temp;
                }
                players = newPlayers;
            }

        }

        //If this is a client then do this
        if( host == false )
        {
            try {
                //If the socket is not yet setup, set it up
                if(socket == null)
                {
                    socket = new DatagramSocket( port );
                }
                byte[] bufer = new byte[256];
                //Using the ID given at the start, send X and Y position to the server
                String msg = "position:" + 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 );
                //Send the data
                socket.send( p );
                Log.d(TAG, "data sent");

            } 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();
            }


        }

        //Host data will ofcourse be differnet

    }
    Log.d(TAG, "Error with run value");
    return "finished";
}

//If a new player needs to be added to the array
private void newPlayer( int idOfNewPlayer )
{
    gameObject temp = new gameObject(BitmapFactory.decodeResource(contextHolder.getResources(), R.drawable.new_player), 250, 300);
    assets[ idOfNewPlayer ] = temp;
}

//Update all the assets in the game
private void updateAssets()
{

}

//Return methods
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; }
//Stop the client server if host
public void stopServers()
{
    if( host == true )
    {
    socket.close();
    server.rtnSocket().close();
    System.gc();
    }
}

public void stopBackground()
{
    socket.close();
    this.cancel( true );
    System.gc();
}
}