2013-04-20 96 views
1

我正在創建一個多客戶端聊天服務器,我非常有信心它會工作(糾正我,如果我錯了),我有問題,在客戶端連接到套接字爲null,因此連接不能因爲我使用if(Socket!= null),所以我沒有得到錯誤,但我會很快解釋我的佈局。服務器以名爲(LaunchServer)的起始類開始,該類使用類對象ClientConnector作爲Minecraft,然後啓動方法runServer()。這裏是這個類的代碼:爲什麼這個套接字爲空?

public class LaunchServer 
{ 
    public static void main(String[] args) 
    { 
     System.out.println("[Info] Running"); 
     ClientConnector Minecraft = new ClientConnector(); 
     Minecraft.runServer(); 
    } 
} 

這很簡單。這將我們帶到ClientConnector類。這裏我們從runServer()方法開始。馬上我們有一個try catch塊。在該塊中,我們打印一條消息,表明服務器正試圖連接到端口1337.然後,我們創建一個名爲serversocket的新ServerSocket。然後,我們向控制檯發送消息,告知我們已經綁定了端口,並且我們正在等待連接。雖然爲true,但我們創建了一個與ServerSocket.accept()相等的新Socket套接字。 OMG他媽的。繼承人的代碼。你知道那是什麼...

import java.util.ArrayList; 
import java.net.*; 
import java.io.*; 

public class ClientConnector 
{ 

public static ArrayList<Socket> Connections = new ArrayList<Socket>(); 

public static void runServer() 
{ 
    try 
    { 
     System.out.println("[Info] Attempting to bind to port 1337."); 
     @SuppressWarnings("resource") 
     ServerSocket serversocket = new ServerSocket(1337); 
     System.out.println("[Info] Bound to port 1337."); 
     System.out.println("[Info] Waiting for client connections..."); 
     while(true) 
     { 
      Socket socket = serversocket.accept(); 
      new ClientHandler(socket).start(); 
      Connections.add(socket); 
     } 

    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
    } 
} 
} 

這需要我們去處理類:

import java.io.*; 
import java.net.*; 


public class ClientHandler extends Thread 
{ 
Socket Socket; 

public ClientHandler(Socket socket) 
{ 
    socket = Socket; 
    System.out.println("[Info] Client connected on port 1337."); 
} 

public void run() 
{ 
    while(true) 
    { 
     for(int i = 0; i < ClientConnector.Connections.size(); i++) 
     { 

      try 
      { 
       if(Socket != null)//This stays null... 
       { 
        ObjectOutputStream Output = new //These can't be created... 
        ObjectOutputStream(Socket.getOutputStream()); 
        ObjectInputStream Input = new ObjectInputStream(Socket.getInputStream()); 
        whileChatting(Input, Output); 
       } 
      } 
      catch (IOException e) 
      { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

public static void sendMessage(String message, String returnedMessage, ObjectOutputStream out) 
{ 
    try 
    { 

     if(!message.isEmpty()) 
     { 
      out.writeObject("\247c[Server]\247d " + message); 
      out.flush(); 
      System.out.println("[Chat] Sent: " + message); 
     } 
     else 
     { 
      out.writeObject(returnedMessage); 
      System.out.println("[Chat] Sent: " + returnedMessage); 
     } 
     out.flush(); 
     System.out.println("[Info] Fluching remaining data to stream."); 
     System.out.println("\n[Server] " + message); 
    } 
    catch(IOException ioException) 
    { 
     System.out.println("[Warning] Error: ioException @ sendMessage line 76."); 
    } 
} 

public static void whileChatting(ObjectInputStream input, ObjectOutputStream output) throws IOException 
{ 
    String message = ""; 
    do 
    { 
     try 
     { 
      message = (String) input.readObject(); 
      System.out.println("\n" + message); 
      sendMessage("", message, output); 
     } 
     catch(ClassNotFoundException classNotFoundException) 
     { 
      System.out.println("[Warning] Error: ClassNotFoundException @ whileChatting line 1-7."); 
      System.out.println("\n idk wtf that user sent!"); 
     } 
    }while(!message.equals("/stop")); 
} 


} 

閱讀run方法。在那裏你會看到null問題

連接會被接受然後傳遞給hander類嗎?一個空連接如何被接受?我的問題是我如何解決這個問題?

+0

沒有在類'ClientHandler'變量名拼寫錯誤 - 你寫的'插座Socket',這是原因所有錯誤。看看構造函數,你已經搞砸了變量名稱 – 2013-04-20 02:20:46

回答

5

問題是由於不推薦的命名約定,導致邏輯錯誤。你不應該用關鍵字命名變量,比如你的Socket變量,並且每個變量都應該有一個可區分的名字。例如不是socket1, socket2,而是serverSocket, clientSocket,因爲這會讓您和其他人更容易閱讀和修復您的代碼。

變化

Socket Socket; 

Socket connectedSocket; 

,並在構造函數

socket = Socket; 

connectedSocket = socket; 

然後最後,在你的run()方法變更

if(Socket != null) 

if(connectedSocket != null) 
+1

+1 - 另一個人的例子**忽略** Java風格約定並被咬住。這裏有一個教訓...... – 2013-04-20 02:39:35

+0

實際上,成員變量應該被命名爲'socket',構造函數代碼應該讀取'this.socket = socket'。它不是'ServerSocket'。 – EJP 2013-04-20 05:23:39

+0

@EJP:好點,我會解決這個問題。儘管通過命名它不僅僅是'socket',我希望能夠幫助區分他的名字。像'connectedSocket'這樣的東西本來會更合適 – TheMerovingian 2013-04-20 05:27:58

相關問題