Reputation: 733
I'm doing a simple login/signup module using TCP with multithreaded server. I want to make my server possible to handle multiple access from client. My first idea was to use a list of client socket to keep track of which client is connecting: accept() a socket - if it's in the list then find it the list and pass it to function to proceed - if it's not, then add it to the list then pass it to function to proceed. It works for the first time access, but in the second time, it's jammed and the client never receive the result. Could you tell me what did I do wrong and what should I do to handle this kind of problem? Thanks!
Server run() method:
@Override
public void run() {
Socket socket = new Socket();
try {
Socket clientSocket = myServer.accept();
if (!listSocket.contains(clientSocket)) {
socket = clientSocket;
listSocket.add(clientSocket);
} else {
for (Socket s : listSocket) {
if (s == clientSocket) {
socket = clientSocket;
break;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
while (true) {
ReceiveObject(socket);
}
}
ReceiveObject() method:
// Receive an object[2]
// the object[0] contains Account object
// the object[1] contains Customer object
// if the object[0] is not null and the object[1] is null => this is a login request
// if both object[0] and object[1] are not null => signup request
public void ReceiveObject(Socket clientSocket) {
try {
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
Object o = ois.readObject();
if (o instanceof Object[]) {
Object[] arr = (Object[]) o;
if (arr[0] != null && arr[0] instanceof Account && arr[1] == null) {
Account acc = (Account) arr[0];
if (CheckAccountExist(acc)) {
SendResult("OK", clientSocket);
} else {
SendResult("FAILED", clientSocket);
}
} else if (arr[0] != null && arr[1] != null && arr[0] instanceof Account && arr[1] instanceof Customer) {
Account acc = (Account) arr[0];
Customer cus = (Customer) arr[1];
String result = "";
if (!CheckAccountExist(acc)) {
result = "OK";
if (AddAccount(acc)) {
if (!CheckCustomerExist(cus)) {
if (AddCustomer(cus)) {
SendResult(result, clientSocket);
} else {
result = "FAILED";
SendResult(result, clientSocket);
}
}
} else {
result = "FAILED";
SendResult(result, clientSocket);
}
} else {
result = "FAILED";
SendResult(result, clientSocket);
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
Upvotes: 0
Views: 240
Reputation: 311050
My first idea was to use a list of client socket to keep track of which client is connecting:
accept()
a socket - if it's in the list then find it the list and pass it to function to proceed - if it's not, then add it to the list then pass it to function to proceed.
Why? It won't be in the list. It's a new connection. It can't possibly be in the list. So, therefore, what exactly is the list for? You don't need it. Just start a new and completely independent thread per accepted socket.
It works for the first time access, but in the second time, it's jammed and the client never receive the result. Could you tell me what did I do wrong and what should I do to handle this kind of problem? Thanks!
Throw it away and have a good look at the Custom Networking section of the Java Tutorial.
NB You should use the same object streams for the life of the socket. You shouldn't need methods with a Socket
parameter: the Socket
should be a member variable of the Runnable
class that handles the connection. So should the object streams.
Upvotes: 3