Question

I have written a server that creates the threads and opens the sockets. The client is written in Flash. The server is not responding anymore to clients after some time.

The server:

public appGameServer(String Ip){
  try{
      _SS = new ServerSocket(appMain.CONFIG_GAME_PORT);
      _SS.setSoTimeout(0);
      _startTime = System.currentTimeMillis();
      _gameServerThread = new Thread(this);
      _gameServerThread.start();
      try{
          _startFunctions();
       }
       catch (Exception e) {
          e.printStackTrace();
          Debug.err.println(e.getMessage());
      }
  } catch (IOException e) {
      Debug.err.println("Could not listen on port " + appMain.CONFIG_GAME_PORT);
      e.printStackTrace();
         System.exit(0);
    }
}

public void _startFunctions(){
    actiuniGlobale.schedule(new TimerTask(){
        public void run(){
        }
    }, 0,500);
}
@Override
public void run(){ 
    while(appMain.isRunning) {
        try {
            _clients.add(new appMainSystem(_SS.accept()));
            _jucatoriOnline = _clients.size();
        }catch(IOException e){
            e.printStackTrace();
            Debug.err.println(e.getMessage());
        }
    }
}

public static void delClient(appMainSystem serverPrincipal) {
    try{
        synchronized (_clients){
            _clients.remove(serverPrincipal);
            _jucatoriOnline = _clients.size();
        }
    }catch(Exception e){
        e.printStackTrace();
       Debug.err.println(e.getMessage());
    }
}

public static void kickAll()
{
    try {
        _SS.close();
    } catch (IOException e) {}

    List<appMainSystem> c = Collections.synchronizedList(new ArrayList<appMainSystem>());
    c.addAll(_clients);
    for(appMainSystem GT : c) {
        try {
             GT.closeSocket();
        } catch(Exception e) {           
            e.printStackTrace();
            Debug.err.println(e.getMessage());};  
    }
}

The packet handler:

public appMainSystem(Socket sock) {
    try{
        _s = sock;
        _s.setSoTimeout(0);
        _in = new BufferedReader(new InputStreamReader(_s.getInputStream()));
        _out = new PrintWriter(_s.getOutputStream(),true);
        try{
            _t = new Thread(this);
            _t.setDaemon(true);
            _t.start();
        }
        catch (Exception e) {
            Debug.err.println(e.getMessage());
            e.printStackTrace();
        }
    }
    catch (IOException e) {
        Debug.err.println(e.getMessage());
        e.printStackTrace();
        if(!_s.isClosed()){
            try{
                _s.close();
            } catch (IOException e1) {Debug.err.println(e1.getMessage());e1.printStackTrace();}
        }
    }
}

public void run(){
    try{
        String packet = "";
        char charCur[] = new char[1];
        while(_in.read(charCur)!=-1 && appMain.isRunning)  {
            if (charCur[0] != '\u0000' && charCur[0] != '\n' && charCur[0] != '\r') {
                packet += charCur[0];
            } else if(!packet.isEmpty()) {
                packet = new String(packet.getBytes(),"UTF8");
                try {
                    verificaPacket(packet);
                } catch(Exception e) {
                    Debug.err.println(e.getMessage());
                    e.printStackTrace();
                }
                packet = "";
            }
        }
    }catch(Exception e) {
        kick();
    }
    finally
    {
        if(!lastPacketRecv.isEmpty()) kick();
    }
}   
public void kick()
{
    try{
        appGameServer.delClient(this);
        closeSockets();
    } catch(Exception e){
        Debug.err.println(e.getMessage());
        e.printStackTrace();
    }
}

public void closeSockets() throws IOException {
    _in.close();
    _out.close();
    if(!_s.isClosed()) closeSocket();
    _t.interrupt();
} 

public void closeSocket()
{
    try {
        _s.close();
    } catch (IOException e) {           
        Debug.err.println(e.getMessage());
        e.printStackTrace();
    }
}
Was it helpful?

Solution

I can't tell from your code if this advice is applicable, but threads that read or write from sockets should do NOTHING else. Read threads should queue their data, and write threads should be fed from a data queue. Reading and writing should be done in different threads.

Otherwise, the unpredictability of buffering and actual data transmission guarantees that unexpected stall conditions will occur.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top