Java Message sent from client to server - java

I'm using a socket to connect my client with the server, I need a way so that when somebody tries to login on the client with an account, it sends the username and password to the server, and checks if the account exists. I just need to know how to make it send the message to the server when they press login.
i tried this to make it send a message to the server
public static void sendmsg(String a, String b)
{
try
{
String host = "127.0.0.1";
int port = 43655;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
//Send the message to the server
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
String sendMessage = a;
bw.write(sendMessage);
bw.flush();
System.out.println("Message sent to the server : "+sendMessage);
//Get the return message from the server
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String message = br.readLine();
System.out.println("Message received from the server : " +message);
}
catch (Exception exception)
{
exception.printStackTrace();
}
finally
{
//Closing the socket
try
{
socket.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}

nice you are working with Sockets, well I have an approach you can try, and maybe if it is useful you can consider for your implementation.
First of all I will create an entity to handle those values and fill it with the incoming data.
class UserAuth {
private String username;
private String password;
//Consider here your getters and setters, I am not including them
}
I will use the entity as the parameter for the method while sending and maybe you can fill it as something like:
UserAuth attemptingUser = new UserAuth(...)
ObjectInputStream works fine for these kind of scenarios. If you still want to work with Strings, you can use BufferedReader and try to merge your username and password as one single String and use the .readLine() method to obtain (separated with commas), then use String methods such Split but I find that could take some more time, should be better if you handle it with an object. But it depends on the complexity you want to add to your application :).
class AuthClient {
public void sendMsg(UserAuth attemptingUser) {
String host = "localhost";
int port = 2055;
//1. Create the socket
Socket sender = new Socket(host, port);
//2. Create an object output stream to write the object into the stream
ObjectOutputStream outputWriter = new ObjectOutputStream(sender.getOutputStream());
//3. Write (send the object)
outputWriter.writeObject(attemptingUser);
//4. Close
outputWriter.close();
sender.close();
}
}
class AuthServer {
ServerSocket ss = new ServerSocket(2055);
public void receiveMsg() {
//1. Accept the connection
Socket conn = ss.accept();
//2. Receive the flow
ObjectInputStream readStream = new ObjectInputStream(conn.getInputStream());
//3. Read the object
UserAuth userReceived = readStream.readObject();
//4. Verify against file, db or whatever
if (userReceived.getUsername().equals("admin") && userReceived.getPassword().equals("admin")) {
//Authentication
}
}
}
(This is added as the part I edit for what you asked me in the comments)
public void sendMsg(String username, String password) {
String host = "localhost";
int port = 2055;
//1. Create the socket
Socket sender = new Socket(host, port);
//2. Create the UserAuth object based on the parameters you received
UserAuth myuser = new UserAuth();
myuser.setUsername(username);
myuser.setPassword(password);
//3. Follow same instructions for the creation of ObjectOutputStream...
ObjectOutputStream objectWriter = new ObjectOutputStream(sender.getOutputStream());
objectWriter.writeObject(myuser);
//That is what I would use if I keep your structure
}
If you want to keep your structure using Strings, I would simplify and reduce impact of I/O by using the String methods. Since you know you are always expecting user/password, I would merge your two params in one single String or use special char and on server side handle with StringTokenizer class. Or maybe handle with the "split" method. You have many options here.
So far, this will be my approach for the problem you are facing. Hope it helps somehow. Best regards and happy coding :).

What you have done looks OK to me but it all depends on what the server is expecting to receive. What is the terminating character as you have not sent one unless it's already contained within your String a variable.
If the server is expecting an end of line character (which you don't currently send) you can use a PrintWriter instead of a BufferedWriter like this
pw = new PrintWriter(socket.getOutputStream(), true);
pw.println(a);
Your server would then be doing something like this
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String value = br.readLine();

Related

send objects from server to client in java sockets

I want to send objects from the server to the client in java sockets. I can send them from client to the server, however I am struggling to send them from server to client. I am new to Java so I'm still learning the basics. I know its something relatively minor that I need to do, however i am struggling with it at the moment. Can someone add the bits of code that i am missing?
Open another connection in another thread and let the client be server, and server be client. So in one thread you send A -> B, in another thread you open another socket and begin to send b B -> A.
The problem with low level sockets is that if one side is writing, the other should be listening. That means you have to implement command-query protocol, which is a heavy task. So with my proposal you will use two ports but you know that you will have 2 pipes of data flow.
A --8888--> B
A <--8889-- B
It will be easier if you are just starting with sockets.
You can use ObjectOutputStream to send an object through the socket and ObjectInputStream to receive one:
private ObjectOutputStream oos;
private ObjectInputStream ois;
public SocketHandler(Socket cs) {
this.oos = new ObjectOutputStream(cs.getOutputStream());
this.ois = new ObjectInputStream(cs.getInputStream());
}
public void sendObject(Object o) {
this.oos.writeObject(o);
this.oos.flush();
}
public Object receiveObject() {
return this.ois.readObject();
}
That was assuming you want to send and receive an Object. You can also use PrintWriter and BufferedReader to send and receive String messages and after parsing it:
private PrintWriter pw;
private BufferedReader br;
public SocketHandler(Socket cs) {
this.pw = new PrintWriter(cs.getOutputStream());
this.br = new BufferedReader(new InputStreamReader(cs.getInputStream()));
}
public void sendMsg(String msg) {
this.pw.println(msg);
this.pw.flush();
}
public String receiveMsg() {
return this.br.readLine();
}
Below I have an example of some Server-Side code that I used for an application a while ago, then I will give you an explanation as to what's going on here:
first you need to create your ServerSocket in order to accept client requests (as you already know):
ServerSocket serverSocket = new ServerSocket(1002);
while(true) {
Then you need to enter a while loop in order to receive requests for as long as the Server program is alive
Socket clientSocket = serverSocket.accept();
System.out.println("Connection made to: " + clientSocket);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
String messageString = "";
String line;
System.out.println("Enter while loop to retrieve client message...");
while((line = br.readLine()) != null) {
String clientRequestLine = line;
if(clientRequestLine.contains("check return user credentials")) {
String userNamePassWord = clientRequestLine.replace("check return user credentials", "");
userNamePassWord = userNamePassWord.trim();
String[] userNamePassWordSplitter = userNamePassWord.split(" ");
String userName = userNamePassWordSplitter[0];
String passWord = userNamePassWordSplitter[1];
System.out.println("Username: " + userName + "\nPassword: " + passWord);
boolean isValidUserNamePassWord = ReturnPatientCredentials.checkUserNamePassWord(userName, passWord);
if(isValidUserNamePassWord) {
System.out.println("valid");
out.println("valid");
}
else {
System.out.println("invalid");
out.println("invalid");
}
}
Above you need to start a BufferedReader in order to store an InputStream (the data) from the client socket. You also need to create a PrintWriter so that you can send data to the OutputStream and you need to pass your clientSocket as the argument for the OutputStream. Next you'll create variables to get the message and the "line" of date from the client and enter a while loop. You can then store the line in a variable and read the data or whatever you need to do. We use our PrintWriter (out) to send data back with the println() method and then we can break out of the loop when needed.

when reading input stream gets few extra bytes before the wanted string

i have a server and a client.
i'm connecting the server from the clients and immediately sends a message,
then i want the server to send message to the clients but when i send the message to the clients.
the input stream of the server which is in the client's code, looks like this:
#$#ok
the "#$#" is bytes that is not my string which i have no idea what are doing there.
this is my client function which connects to the server sends data and waits for the the server to send:
public void connectToServer(String ip, int port, String boardSize) throws UnknownHostException, IOException, ClassNotFoundException {
server = new Socket(ip, port);
serverInput = new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter serverOutput = new PrintWriter(new OutputStreamWriter(server.getOutputStream()));
ObjectOutputStream player1OutputData = new ObjectOutputStream(player1.getOutputStream());
ObjectOutputStream player2OutputData = new ObjectOutputStream(player2.getOutputStream());
serverOutput.println(boardSize);
serverOutput.flush();
String isGameStarted = serverInput.readLine();
if(isGameStarted.equals("ok")) {
...
}
}
and this is my server code which send the "ok" string:
BufferedReader player1Input = new BufferedReader(new InputStreamReader(player1.getInputStream()));
BufferedReader player2Input = new BufferedReader(new InputStreamReader(player2.getInputStream()));
PrintWriter player1Output = new PrintWriter(new OutputStreamWriter(player1.getOutputStream()));
PrintWriter player2Output = new PrintWriter(new OutputStreamWriter(player2.getOutputStream()));
String gameStarted = "ok"
player1Output.println(gameStarted);
player1Output.flush();
player2Output.println(gameStarted);
player2Output.flush();
System.out.println("message sent to clients: \"" + gameStarted + "\"");
player1OutputData.writeObject(gameBoard);
player2OutputData.writeObject(gameBoard);
i didnt send any garbage data, why would it be there?
and what should i do to clean it up?
thanks!
EDIT: ok so i think i know when this is happening,
after i send "ok" i want to send a string matrix to the clients as well, so when i do that for some reason the "String isGameStarted = serverInput.readLine();"
line isn't getting the "ok" string, it is getting the array, and after i remove those lines(where i send the array), the garbage bytes remain there, i don't know why.

send message to specific clients using java

How can i send message from server to any specific client. I have the concept of how to do it like i have to make a list of all the clients connected to server and then by iterating each client i can send message but i will be thankful if any one can help me by code.I have searched many codes but i didn't get any considerable help from them Code shouldn't be GUI based. Thanks in advance.Sorry for my bad English.
This is my code in which message is send to all clients but i want to send message to a client of my choice using clients ipaddress
Map<Integer, java.net.Socket> clients = new HashMap<Integer, java.net.Socket> ();
socket = serverSocket.accept();
// Add the socket to a HashMap
clients.put(socket.getPort(), socket);
for (Iterator<Integer> iter = clients.keySet().iterator(); iter.hasNext(); )
{
int key = iter.next();
java.net.Socket client = clients.get(key);
// Sending the response back to the client.
// Note: Ideally you want all these in a try/catch/finally block
OutputStream os = client.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("Some message");
bw.flush();
}
What I would do is create a Client class:
class Client
{
private String userName;
private String ipAddress;
private java.net.Socket socket = null;
public Client (String userName, String ipAddress, java.net.Socket socket)
{
this.userName = userName;
this.ipAddress = ipAddress;
this.socket = socket;
}
public java.net.Socket getSocket()
{
return this.socket;
}
}
Instead of adding just the socket and port number to the map, I would map the combination of the userName and ipAddres to a Client object.
socket = serverSocket.accept();
// get the username from the socket
// get the ipAddress from the socket
Client c = new Client(userName, ipAddress, socket);
// Add the client to a HashMap
clients.put(userName + ":" + ipAddress, c);
Now, you can send a message to a specific client based on the username and ipAddress:
public void sendToOneClient (String userName, String ipAddress, Map<String, Client> clients)
{
Client c = clients.get(userName + ":" + ipAddress);
java.net.Socket socket = c.getSocket();
// Sending the response back to the client.
// Note: Ideally you want all these in a try/catch/finally block
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("Some message");
bw.flush();
}
I'd use Socket.getInetAddress() and compare the result to whatever you have the IPs you want to send to in. Personally, I'd use a String[] or ArrayList<String> for that. Here's an example:
ArrayList<String> addresses;
//TODO: Add things to 'addresses'
clients.put(socket.getPort(), socket);
for (Iterator<Integer> iter = clients.keySet().iterator(); iter.hasNext(); )
{
int key = iter.next();
java.net.Socket client = clients.get(key);
//Checking to make sure it's a client we want to send to.
if (addresses.contains(client.getInetAddress().toString()) {
// Sending the response back to the client.
// Note: Ideally you want all these in a try/catch/finally block
OutputStream os = client.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write("Some message");
bw.flush();
}
}
Alternatively, you could store the sockets in your HashMap by the InetAddress instead.
You can store a relationship between how you want to look up the client with the socket that they are on. The natural way to do this is with a map, like
Map<String, Socket> sockets = new HashMap<String,Socket>();
...
ServerSocket ss = ...;
Socket s = ss.accept();
String username = getUserName(s);
sockets.put(username, s);
Obviously, in this example here, the client would have to send his/her userName in a format which you expect to receive after making the Socket connection
I have found that it is effective to create an object type that can hold both a unique name or id be it an int or a String and also a Socket. You could store instances of this object in an ArrayList (or any other list) and iterate through them searching for the name or id that you want to use.
This is what I did for my program.Here I used the ">>" string to specify that a message should be sent to a particular user. (e.g.: "Ross>>Hi Ross What's Up?" means that the message should be sent to the user named 'Ross'). I used a HashMap(named 'WritersMap') to keep details as KEY-VALUE pairs. Key will be the name of the user who sends the particular message and Value will be that message. 'in' is a BufferedReader instance.
while (true) {
String input = in.readLine();
if (input == null) //if there is no input,do nothing
{
return;
}
//when a user sends a message to a specific user
else if(input.contains(">>")) //checks whether the message contains a >>
{
String person=input.substring(0,input.indexOf(">")); //extract the name of the destination user
for(HashMap.Entry<String,PrintWriter> entry:writersMap.entrySet()) //find the destination user from the users list
{
if(entry.getKey().matches(person)) //if the destination user is found
{
PrintWriter writer=entry.getValue();
writer.println("MESSAGE " + name + ": " + input);
}
}
}
else //when a user sends a broadcast message to all users
{
for(HashMap.Entry<String,PrintWriter> entry:writersMap.entrySet()) //find the destination user from the users list
{
PrintWriter writer=entry.getValue();
writer.println("MESSAGE " + name + ": " + input);
}
}
}

Keep client to server connection open and close on request

I have a TCP client application in Java, through this application i can communicate with a server application.
I have a simple method sendCommand which sends the message to the server:
void sendCommand(String command) throws IOException {
String ipaddress = "192.168.0.2";
Socket commandSocket = null;
PrintWriter out = null;
BufferedWriter out = null;
BufferedReader in = null;
BufferedWriter outToDetailFile = null;
FileWriter fstream = null;
String version = "";
int numberOfBallsInGame;
int ledCycleState = 1;
commandSocket = new Socket(ipaddress, 7420);
out = new BufferedWriter(new OutputStreamWriter(commandSocket.getOutputStream()));
in = new BufferedReader(new InputStreamReader(commandSocket.getInputStream()));
out.write("c");out.flush();
out.write(command);out.flush();
String message = in.readLine();
//System.out.println(message);
out.close();
in.close();
commandSocket.close();
}
Now, because the server application is on the machine which does not accept more than 2 connections in 20 seconds i need to modify my method and "split" it in 3 different methods (i think).
My plan is the following:
I would like to call the connection to the server in one thread, keep it opened untill i want to close it, but i should be able to send the commands between opening the connection and closing it.
I'm pretty new to Java and i'll try to explain here exactly what i want to do:
1) I want to open the connection to TCP server.
2) After opening the connection i want to be able to send commands to an already opened connection by calling this method:
void sendCommand(String command) throws IOException {
out.write("c");out.flush();
out.write(command);out.flush();
}
And after i'm finished with sending commands i want to call some method to close my running connection.
Because i'm pretty new to java it would be very nice if someone could show me how to achieve this or modify my method.
Thank you in advance,

server client communication java

I have this client, the server information is not important. The output of this code is very random.
class Client {
public static void main(String args[]) throws Exception
{
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("127.0.0.1", 10004);//this will become the addr of the server you want to input.
InetAddress host = clientSocket.getInetAddress();
// System.out.println(host);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
boolean exit = false;
while (!exit) {
while (inFromServer.ready()) {
System.out.println(inFromServer.readLine());
}
String sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + "\n");
}
clientSocket.close();
}
}
If I run this in debug mode, it has always the correct result. E.g.
please insert password
the user types pass
pass correct
please type command
and you type command
etc
etc
When it's not in debug mode, all goes wrong. I don't even get the initial request from server. What is going on? I think the read line might be executed too fast?
in.ready() does not wait for any data to be available. It the server hasn't sent the data yet when you client reads that line, you're going to skip the readLine() completely.
Just remove that while and do a plain readLine().
If there are phases where you need to wait for multiple lines from the server, you'll need to implement more logic. Usually, the server will send an "end of message" marker to signify to the client that it is done. For example, when the server is done, it could send the message "END-OF-MESSAGE". In the client code, you would do:
boolean serverDone = false;
while (!serverDone) {
String message = in.readLine();
if (message == null) {
// handle this problem: the server has closed the connection
serverDone = true; // or return, or throw
} else if ("END-OF-MESSAGE".equals(message)) {
serverDone = true;
}
}

Categories