Извиняюсь, был в отпуске )
Похоже я несовсем правильно описал ситуацию (или теперь по какимто причинам програма ведет себя по другому). Просто когда клиентов больше чем 3, иногда разрывается соединение раньше времени с некоторыми клиентами.
Как все работает: после конекта к серверу клиент шлет строку "char(0x01)|ИМЯ". Сервер сохраняет ИМЯ и высылает клиенту строку "r", получив которую клиент закрывает свой сокет. Cервер, обнаружив разрыв соединения, выводит сообщение, что клиент с именем ИМЯ отсоеденился. Проблема в том, что если сделать, скажем 10 клиентов (лучше сразу 500 для 100% эфекта) то будет видно, что с некоторыми клиентами связь разрывается еще до того, как сервер сохранит имя этого клиента. Я уверен, что что-то не то с дисконектом, потомучто если ни одного клиента не закрывать, то ни одно из соединений не закрывается. Если-же все закрывать сразу после регистрации (после получения строки "r"), то некоторые соединения разрываются сами по себе (иначе сервер имел-бы имя этого клиента)
Вот сам код
Сервер
Main.java
| Код | package testServer;
import java.io.IOException; import java.net.ServerSocket;
public class Main {
static ServerSocket serverSocket = null; /** * @param args */ public static void main(String[] args) { try { serverSocket = new ServerSocket(6899); serverSocket.setSoTimeout(0); System.out.println(serverSocket.toString()); while(true){ try{ new Client(serverSocket.accept()).run(); } catch(IOException e){ System.out.println(e.getMessage()); } } } catch(IOException e){ System.out.println("Server socket: " + e.getMessage()); } } }
|
Client.java
| Код | package testServer;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket;
public class Client extends Thread { private Socket clientSocket = null; private BufferedReader in = null; private PrintWriter out = null; private boolean hasName = false; private String player_name = ""; public Client(Socket socket) { this.clientSocket = socket; //create I/O streams this.crateStreams(); //start listening loop new Thread() { public void run(){ String clientInput = ""; try { while ( (in != null) && (clientInput = in.readLine()) != null){ char first_char = clientInput.charAt(0); if ((hasName) && (first_char != ' ')){ //something } else if (first_char == (char)((int)0x01)) { //register name hasName = true; player_name = clientInput.substring(2); System.out.println(player_name + " connected"); out.println("r"); out.flush(); } } //System.out.println(player_name + " disconnected"); } catch(IOException e){ if (player_name == "") { System.out.println("!!!!!!!!!! Client with no name disconnected !!!!!!!!!!"); } else { System.out.println(player_name + " disconnected"); } }; } }.start(); } /** * Sets I/O streams for connected client */ private void crateStreams() { //creating output stream try{ out = new PrintWriter(clientSocket.getOutputStream(), true); } catch(IOException e){ System.out.println("Error creating PrintWriter"); } //creating input stream try{ in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); } catch(IOException e){ System.out.println("Error creating BufferedReader"); } } }
|
Клиент
Main.java
| Код | package emulator;
public class Main { /** * Server host */ private static String host = "127.0.0.1"; /** * Server port */ private static int port = 6899; /** * how much client threads to start */ private static int clients = 9; /** * how much times clients will reconnect to server */ private static int reconnects = 1; /** * clients name prefix */ private static String name_prefix = "Client";
/** * @param args not used */ public static void main(String[] args) { int i = 0; for (i=0; i<clients; i++) { new Client(host, port, reconnects, name_prefix + " " + i).start(); } }
}
|
Client.java
| Код | package emulator;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket;
public class Client extends Thread { private Socket clientSocket = null; private PrintWriter os = null; private BufferedReader in = null; private String host = ""; private int port = 0; private String name = ""; private int reconnects = 0; private boolean accepted = false; public Client(String host, int port, int reconnects, String name) { this.host = host; this.port = port; this.name = name; this.reconnects = reconnects; } public void run() { int i = 0; for (i=0; i<reconnects; i++) { try { clientSocket = new Socket(host, port); os = new PrintWriter(clientSocket.getOutputStream()); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); if ( (os == null) || (in == null) ) { System.out.println("Can't create I/O buffer"); System.exit(1); } else { setPlayerName(name); } String serverInput = ""; while( (in != null ) && (accepted == false) && (serverInput = in.readLine()) != null) { if(serverInput.charAt(0) == 'r') { //registered accepted = true; System.out.println("client " + name + " accepted"); } } if (in == null) { System.out.println("connection error"); } accepted = false; System.out.println(name + " disconnected"); clientSocket.close(); } catch(IOException e){ System.out.println("Socket error: " + e.getLocalizedMessage() + "; " + host + ":" + port); } } System.exit(4); } public void setPlayerName(String s){ if (os != null) { os.println(((char)((int)0x01)) + "|" + s); os.flush(); System.out.println("Name sent: " + s); } } }
|
Вот пример того, что выводится:
| Код | !!!!!!!!!! Client with no name disconnected !!!!!!!!!! Client 136 disconnected !!!!!!!!!! Client with no name disconnected !!!!!!!!!! Client 64 disconnected
|
Если чтото плохо обьяснил - говорите, постараюсь уточнить. |