我正在使用TCP套接字编写一个简单的客户端 - 服务器应用程序。它适用于多线程原则,允许多个客户端连接到同一服务器。
我在弄清楚套接字出现的一些错误时遇到了一些麻烦,我在这个环境中相当新,你可能会说。
我将向您展示我拥有的代码,以及我从中得到的输出,但基本上问题在于客户端与服务器的连接,并且我查看了所有代码但仍无法找到这有什么不对。
服务器:
public static ArrayList<String> userList = new ArrayList<String>();
public static int index;
public static String date;
public static void main(String args[]) throws Exception {//inicio main
ServerSocket server = new ServerSocket(6500); //Create socket on port 6500
System.out.println ("Server started on port 6500");
while (true){ //Waiting for clients
System.out.println("Server waiting for client connections..");
Socket socket = null;
BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
String line = null;
socket = server.accept();
// Blacklist verification
while ((line = reader.readLine()) != null) {
if (line.equals(socket.getInetAddress().toString())) {
System.out.println("IP Blacklisted: " + socket.getInetAddress().toString());
System.out.println("Closing connection to " + socket.getInetAddress().toString());
PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
checkBlack.println("***BLACKLISTED***");
reader.close();
checkBlack.close();
socket.close();
break;
}
}//End of Blacklist Verification
//Sending feedback in case of approved client
try {
PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
checkBlack.println("***NBLACKLISTED***");
checkBlack.close();
} catch (SocketException e) {
}
userList.add(socket.getInetAddress().toString()); //Add connected user's IP to USERLIST
System.out.println("New connection..");
System.out.println("Size of UserList: " + userList.size());
Thread t = new Thread(new EchoClientThread(socket));
t.start(); //Starting Client Thread
}//End of Waiting for Clients
}//End of Main
public static class EchoClientThread implements Runnable{
private Socket s;
public EchoClientThread(Socket socket) {
this.s = socket;
}
public void run() {
String threadName = Thread.currentThread().getName(); //Thread Name
String stringClient = s.getInetAddress().toString(); //Client IP
System.out.println("Connected to " + stringClient);
try{
BufferedReader input = new BufferedReader(
new InputStreamReader(s.getInputStream()));
PrintStream output = new PrintStream(
s.getOutputStream(),true);
String line;
while ((line = input.readLine()) !=null) { //Input Cycle
System.out.println (stringClient+": "+threadName+": "+line); //Print command from client
if (line.equalsIgnoreCase("9")){ //Exit
break;
}
else if (line.equalsIgnoreCase("1")){ //Send List of Online Users
System.out.println("Option 1: Sending list of online users to " + stringClient);
output.println(" ");
output.println("List of Online Users:");
output.println(" ");
for(int i=0;i<userList.size();i++){
output.println(userList.get(i));
}
}
else if (line.equalsIgnoreCase("2")) { //Send message to a single user
System.out.println("Nothing here yet..");
}
else if (line.equalsIgnoreCase("3")) { //Send message to all the online users
System.out.println("Nothing here yet..");
}
else if (line.equalsIgnoreCase("4")){ //Send User Blacklist
System.out.println("Option 4: Sending user blacklist to " + stringClient);
BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
String lineRead = null;
output.println(" ");
output.println("User Blacklist:");
output.println(" ");
while ((lineRead = reader.readLine()) != null) {
output.println(lineRead);
}
reader.close();
}
else{
output.println("Unknown command.");
}
output.println("***CLOSE***"); //Closes client's input cycle
output.println("***NBLACKLISTED***"); //Sending feedback in case of approved client
}//Input Cycle End
output.println("See you later!");
input.close(); //Closes inputStream
output.close(); //Closes outputStream
s.close(); //Closes Socket
}
catch (Exception e){
System.err.println("Server Side Error!");
System.out.println(e);
}
userList.remove(s.getInetAddress().toString());
System.out.println("Client "+ stringClient+" was disconnected!");
}//End of run()
}//End of EchoClientThread
}//End of EchoServerThread
客户端:
public static void main(String args[]) throws Exception {
if (args.length !=1){
System.err.println ("usage: java EchoClient2 <host>");
System.exit(1);
}
String host = args[0];
int port = 6500;
String cmd, line;
Socket socket = new Socket(host,port);
BufferedReader input = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintStream output = new PrintStream(socket.getOutputStream(),true);
while( true ) {//Input cycle
Scanner scan = new Scanner (System.in);
if (input.readLine().equals("***BLACKLISTED***")) {
System.out.println("IP is Blacklisted");
break;
}
System.out.println(" ");
System.out.println("CLIENT MENU");
System.out.println(" ");
System.out.println("1 - List on-line users");
System.out.println("2 - Send message to a single user");
System.out.println("3 - Send message to all on-line users");
System.out.println("4 - List Blacklisted Users");
System.out.println("9 - Exit");
System.out.println(" ");
System.out.print(host+":"+port+"#>"); //Command prompt
cmd = scan.nextLine(); //Scanning command to send to the server
output.println(cmd); //Sending command to the server
if ( cmd.equalsIgnoreCase("9")){
System.out.println("Exiting..");
break;
}
try {
while (!(line = input.readLine()).equals("***CLOSE***")) { //Input Cycle
System.out.println (line); //Prints server answer
}
} catch (Exception e) {
System.err.println("Client Side Error!");
System.out.println(e);
break;
}
}//End of Cycle
System.out.println("Connection Terminated");
input.close(); //Closes inputStream
output.close(); //Closes outputStream
socket.close(); //Closes Socket
}
}
所以服务器启动正常,输出如下:
Server started on port 6500
Server waiting for client connections..
但是一旦我尝试与客户端连接,就会发生这种情况:
服务器端:
Server started on port 6500
Server waiting for client connections..
New connection..
Size of UserList: 1
Server waiting for client connections..
Connected to /127.0.0.1
java.net.SocketException: Socket is closed
Server Side Error!
Client /127.0.0.1 was disconnected!
但是在客户端,它仍然显示输入菜单和命令提示符,如下所示:
CLIENT MENU
1 - List on-line users
2 - Send message to a single user
3 - Send message to all on-line users
4 - List Blacklisted Users
9 - Exit
127.0.0.1:6500#>
当我在客户端提示输入内容时,我得到:
127.0.0.1:6500#>1
Client Side Error!
java.net.SocketException: Software caused connection abort: recv failed
Connection Terminated
我知道这些错误意味着什么,Socket is closed
几乎是不言自明的,但我无法找到使套接字关闭的代码问题。
非常感谢任何帮助。
答案 0 :(得分:2)
你的黑名单机制不太正确。
当您关闭与套接字关联的流时,它也会关闭套接字。
因此服务器正在关闭它获得的任何套接字,然后将其交给线程, 尝试使用套接字并失败。
// Blacklist verification
while ((line = reader.readLine()) != null) {
// blah blah blah
}//End of Blacklist Verification
//Sending feedback in case of approved client
try {
PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
checkBlack.println("***NBLACKLISTED***");
checkBlack.close(); // <== why are you closing the stream?
} catch (SocketException e) {
}
试试这个
// Blacklist verification
while ((line = reader.readLine()) != null) {
// blah blah blah
}//End of Blacklist Verification
//Sending feedback in case of approved client
try {
socket.getOutputStream().write("***NBLACKLISTED***\n".getBytes());
} catch (SocketException e) {
e.printStackTrace();
}
调试器是你的朋友。