The Student Room Group

Communication protocol help

I'm designing a communications system for my project. However, I'm having some trouble handling packets. My communications system is written in java.net using ServerSocket,Socket, BufferedReader, and PrintWriter.

Currently, my system listens for packets every 500ms. It handles the login packet fine but it fails to handle the post-login packets. Every 500ms, I need my server to handle login and post-login packets. How would I design a method that would detect and process post-login packets? The login packet consists of the handshake code, username, and password. Post-login packets consist of the handshake code, user id, event id and other relevant parameters.

This is my server sided decoder
protected void decode(Socket server)throws Exception {
final BufferedReader reader = newBufferedReader(new InputStreamReader(server.getInputStream()));
final int handshake =Integer.parseInt(reader.readLine());
if (handshake == LOGIN) {
final Session session = newLoginSession(server, reader);
session.read(-1);
} else if (handshake == POST_LOGIN) {
final int index =Integer.parseInt(reader.readLine());
final int opcode =Integer.parseInt(reader.readLine());
final Session session =store.get(index).getSession();
session.reader = reader;
session.read(opcode);
}

}

@Override
public void run() {
Socket server;
try {
server = serverSocket.accept();
server.setTcpNoDelay(false);
decode(server);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
These are my incoming packets from theclient to the server
public void sendLogin() {
write.write("100":wink:;//loginhandshake
write.write('\n':wink:;
write.write("raees2":wink:;//username
write.write('\n':wink:;
write.write("LOL2":wink:;//password
write.write('\n':wink:;
write.flush();
}

public void sendPrintId() throwsNumberFormatException, IOException {
final BufferedReader reader = newBufferedReader(new InputStreamReader(client.getInputStream()));
final int id =Integer.parseInt(reader.readLine());
System.out.println(id);

write.write("101":wink:;//postlogin handshake
write.write('\n':wink:;
write.write(Integer.toString(id));//userid
write.write('\n':wink:;
write.write(Integer.toString(0));//eventid
write.write('\n':wink:;
write.write(Integer.toString(10003));//eventparameter
write.write('\n':wink:;
write.flush();
}

public void sendDisconnection() throwsNumberFormatException, IOException {
final BufferedReader reader = newBufferedReader(new InputStreamReader(client.getInputStream()));
final int id =Integer.parseInt(reader.readLine());
System.out.println(id);

write.write("101":wink:;//post-loginhandshake
write.write('\n':wink:;
write.write(Integer.toString(id));//userid
write.write('\n':wink:;
write.write(Integer.toString(1));//eventid
write.write('\n':wink:;
write.flush();
}
Reply 1
Why are you logging in using sockets? I mean I know you can, but most people tend to use HTTP Post requests to handle authentication of users.
Original post by Async
Why are you logging in using sockets? I mean I know you can, but most people tend to use HTTP Post requests to handle authentication of users.


idk much about the HTTP protocol. i thought you could only use it for web-based applications.
Reply 3
Nah it doesn't have to be a web based application, you can send a HTTP request from a non web based platform. Java has the libraries to do this.
Reply 4
Original post by Async
Why are you logging in using sockets? I mean I know you can, but most people tend to use HTTP Post requests to handle authentication of users.


Most protocols use sockets to handshake, http Post is only used for web based applications. For example, pop3, FTP, telnet etc all use tcp sockets for authentication.

OP, have you considered using wireshark to see what packets are actually being sent and how?

At a first glance, it seems you may be missing carriage return bytes. ("\r")
Reply 5
You need a loop to continuously read info from the socket.
Looks like your just accepting the connection and reading one line.
(edited 8 years ago)
Reply 6
Original post by INTit
You need a loop to continuously read info from the socket.
Looks like your just accepting the connection and reading one line.


And this.
Original post by INTit
You need a loop to continuously read info from the socket.
Looks like your just accepting the connection and reading one line.


yes this is what is needed. i'm just not sure how i'd implement it. could you explain further please?
Reply 8
Bind socket to port

While(true) do
Accept connection
Recv buffer from socket
If username in buffer
Handle Usenane
Elif Password in buffer
Handle password
Else
Do something else
Original post by tim_123
Bind socket to port

While(true) do
Accept connection
Recv buffer from socket
If username in buffer
Handle Usenane
Elif Password in buffer
Handle password
Else
Do something else


i had all that code nested in a while(true) loop previously. it still didn't handle all the packets properly. i decided to run the code in a scheduled executor cycling every 500ms. still no luck :/
i think i'll try that wireshark thing tomorrow. i'm going to sleep now.
Reply 10
You dont need to loop acceptance of the connection as serverSocket.accept() blocks.
What you need to loop is the reading of the data from the socket.

Open socket
Accept Connection
LOOP
readLineOfData
parseLineOfData - and do other stuff like responding
GOTO loop

Thats the flow you want.

Point to remember is that you are using blocking sockets:
serverSocket.accept() -blocks the thread of execution untill the connection is established.
reader.readLine() - blocks untill a newline character is recieved.

If we look at your send code


public void sendPrintId() throwsNumberFormatException, IOException {
final BufferedReader reader = newBufferedReader(new InputStreamReader(client.getInputStream()));
final int id =Integer.parseInt(reader.readLine());
System.out.println(id);

write.write("101":wink:;//postlogin
write.write('\n
write.write(Integer.toString(id));//userid
write.write('\n
write.write(Integer.toString(0));//eventid
write.write('\n
write.write(Integer.toString(10003));//eventparameter
write.write('\n
write.flush();
}


Your client app is sending 4 lots of data terminated by newlines. So to read all that readline is going to have to be called 4 times. Thats why you need the loop.
(edited 8 years ago)
Reply 11
Original post by tim_123
Most protocols use sockets to handshake, http Post is only used for web based applications. For example, pop3, FTP, telnet etc all use tcp sockets for authentication.


Yes I'm aware of that, I didn't say HTTP POST isn't only for web based application, I said you can send HTTP POST requests from a non web based server.
Thanks guys, I got it working. It was caused by my misunderstanding of blocking and non-blocking IO.

Quick Reply

Latest

Trending

Trending