How to use UDP with multiple Clients in Java - java

I have the following Situation.
I have a Server class.
I have a Client class.
I have a MultiServerThread class.
When a Client connects to a Server, the Server creates a new MultiServerThread, which is processing the Input from the Client. That way I can have multiple Clients. So far so good.
The connection goes via TCP.
A short example:
Server class:
...
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = null;
boolean listening = true;
try {
serverSocket = new ServerSocket(9999);
} catch (IOException e) {
System.err.println("Could not listen on port: " + serverSocket.getLocalPort() + ".");
System.exit(-1);
}
while (listening) {
new MultiServerThread(serverSocket.accept()).start();
}
serverSocket.close();
}
...
Client class:
...
public static void main(String[] args) throws IOException {
socket = new Socket(hostname, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
stdIn = new BufferedReader(new InputStreamReader(System.in));
String fromServer;
String fromUser;
while ((fromServer = in.readLine()) != null) {
System.out.println("Server: " + fromServer);
if (fromServer.equals("Bye.")) {
break;
}
fromUser = stdIn.readLine();
if (fromUser != null) {
System.out.println("Client: " + fromUser);
out.println(fromUser);
}
}
out.close();
in.close();
stdIn.close();
socket.close();
}
...
MultiServerThread class:
...
public MultiServerThread(Socket socket) throws SocketException {
super("MultiServerThread");
this.socket = socket;
// dSocket = new DatagramSocket(4445);
}
public void run() {
try {
PrintWriter myOutput = new PrintWriter(socket.getOutputStream(), true);
BufferedReader myInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
myOutput.println("Connected to client and ready to accept commands.");
while ((clientInput = myInput.readLine()) != null) {
//A SIMPLE LOGIN A USER
if (clientInput.contains("!login")) {
//save some string given by client into loggedUser
String loggedUser = clientInput.substring(7);
}
myOutput.close();
myInput.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
What I need is:
I need to implement a notification that comes from a Server when for example the Username is "Bob". If the username is "Bob", the server should give a notification to the Client "Bob is here again!". In my project/homework this should be done with datagrams in Java.
So if the clientinput is "!login bob" then a datagram packet with the message ("Bob is here again!") should be sent to the client.
Question: Where exactly should I put the code of the Datagram request in? Can I put the datagram packet request into the MultiServerThread or into the Client?
It would be easier in the MultiServerThread because it already handles the !login.
Here:
if (clientInput.contains("!login")) {
//save some string given by client into loggedUser
String loggedUser = clientInput.substring(7);
//send datagram request to Server???
}
But this is going against the principle of networking?

you need to send the UDP port number to your client through the initial TCP connection. Then you start listening for UDP datagrams on your client on that port number. All other communications from server -> client will be on this udp socket. This is what your assignment suggests

I got it working ;-)
I definied a udp port in the thread and client class...
the client class got his port with arguments... it gave the udp Port to the thread... so both had the udp ports ;)

Related

Java Client not receiving C# Server response TCP

Can somebody explain to me what I am doing wrong.First time I try to implement TCP between Java and C#:
Sever code c#
`
public void CreateServer()
{
Thread thread = new Thread(() =>
{
IPAddress addr = IPAddress.Parse(localIP);
tcpListener = new TcpListener(addr, 5053);
if (tcpListener != null)
{
tcpListener.Start();
while (!end)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
var ip = ((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address.ToString();
Console.WriteLine("Client connected from "+ip);
NetworkStream clientStream = tcpClient.GetStream();
StreamReader reader = new StreamReader(clientStream, Encoding.UTF8);
try
{
string request = reader.ReadToEnd();
Console.WriteLine("Message from client: " + request);
Byte[] StringToSend = Encoding.UTF8.GetBytes("Server");
clientStream.Write(StringToSend, 0, StringToSend.Length);
Console.WriteLine("Sending response back");
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
});
thread.Start();
}
`
Client code java
`
public class TCP {
private String IP;
private InetAddress server;
private Socket socket;
public TCP(String IP) {
this.IP = IP;
}
protected void runTCP() {
try {
server = InetAddress.getByName(IP);
socket = new Socket(server, 5053);
System.out.println("Client connected. Listening on port 5053");
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendMessage(String message) {
try {
System.out.println("Sending data...");
if (socket.isClosed()) socket = new Socket(server, 5053);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.print(message);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void getResponseServer() {
Thread thread = new Thread() {
#Override
public void run() {
try {
System.out.println("Attempting to get response...");
if (socket.isClosed()) socket = new Socket(server, 5053);
BufferedReader mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String mServerMessage = mBufferIn.readLine();
System.out.println("Server message: " + mServerMessage);
} catch (Exception e) {e.printStackTrace();}
}
};
thread.start();
}
}
`
Output on server I get when sending "Hello" from client to server:
Client connected from 192.16.... Message from client: Hello Sending response back Client connected from 192.16....
Output on client:
Client connected. Listening on port 5053 Sending data... Attempting to get response...
Never gets response... Why?
Tried researching but found nothing yet, tried other code but didnt work aswell...
sorry , I can't comment. maybe you can use telnet command to vertify c# code is corrent.
telnet ip port
first, locate problem, then solve it.
if server is ok , we can use nc command vertify client code, I have test your java code , except every send data will close socket , other is ok.
Fixed it by removing writer.close() cause that causes socket closing and makes another connection to the server by creating again the socket which makes the server wait for a stream of data and the client wait for a response...
System.out.println("Sending data...");
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
writer.println(message);
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}

Server doesn't listen to requests

as a part of my homework I have to build two classes one listener and one that is making the requests to the server (the server is already written by my teacher and I don't know how code looks like). In theory: The server that I'm connected to should reply with the exact same requests I sent to him. But in practice I get nothing back.
public class Listenerthread extends Thread {
Socket s;
Scanner answerServer;
public Listenerthread(Socket socket) {
this.s = socket;
this.answerServer = new Scanner(new BufferedReader(new InputStreamReader(s.getInputStream())));
}
public void run() {
System.out.println("Listening to the responses from the server......");
while (true) {
if (answerServer.hasNext()) {
System.out.println(answerServer.nextLine());
}
}
}
}
public class Mainthread {
public static void main(String[] args) throws ParseException {
Socket s = new Socket("someServer", 9999);
Listenerthread server = new Listenerthread(s);
server.start();
if (s.isConnected()) {
System.out.println("Connected");
}
String req = "Heyyy mate"; // server should sent me this back
PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
pw.println(req);
pw.flush();
//pw.close();
//s.close();
}
}
Update: A comment that OP left on the question after I started writing this answer shows that OP does not actually need to handle the server side of the communications. I will leave this answer for now in case it could still be useful.
When you have a client/server model, you should use a ServerSocket on the server side, as you alluded to in your question but then do not appear to have done in your code.
ServerSocket
Here is a ServerSocket example that may clear that up.
ServerSocket serverSocket;
public void serverSocketTest()
{
serverSocket = new ServerSocket(9999);
// each of the below methods will happen on separate threads
new Thread(this::serverSideAcceptConnectionFromClient).start();
new Thread(this::clientSideConnectToServer).start();
}
public void clientSideConnectToServer()
{
try {
System.out.println("Client is trying to connect to server...");
Socket connectionToServer = new Socket("localhost", 9999);
OutputStream thisGoesToTheServer = connectionToServer.getOutputStream();
InputStream thisIsDataComingFromServer = connectionToServer.getInputStream();
System.out.println("Client successfully connected to server.");
} catch(IOException ex) {
System.out.println("Connection to server failed. (" + ex + ")");
}
}
public void serverSideAcceptConnectionFromClient()
{
try {
System.out.println("Server is listening for potential clients...");
Socket connectionFromClient = serverSocket.accept();
InputStream thisIsDataComingFromClient = connectionFromClient.getInputStream();
OutputStream thisIsGoesBackOutToClient = connectionFromClient.getOutputStream();
System.out.println("Server accepted a client");
} catch(IOException ex) {
System.out.println("Error while listening for clients. (" + ex + ")");
}
}

java Socket programming Server Client

I'm trying to program a Server Client program where the CLIENT will be prompt if the SERVER closes or loses connection. What happens is once I connect the server and the client then disconnects the server it doesn't go to the ConnectException part
example: I opened the Server and Client connects, in the Client it will show that "You are connected to the Server", then if the Server disconnects there should be a "Server is disconnected". and when the Server reopens it will prompt the Client that he's connected to the Server
How can I continuously check if the Server is open or disconnected
here's my code:
SERVER
public class Server
{
private static Socket socket;
public static void main(String[] args)
{
try
{
int port = 25000;
ServerSocket serverSocket = new ServerSocket(port);
//Server is running always. This is done using this while(true) loop
while(true)
{
//Reading the message from the client
socket = serverSocket.accept();
System.out.println("Client has connected!");
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String number = br.readLine();
System.out.println("Message received from client is "+number);
//Multiplying the number by 2 and forming the return message
String returnMessage;
try
{
int numberInIntFormat = Integer.parseInt(number);
int returnValue = numberInIntFormat*2;
returnMessage = String.valueOf(returnValue) + "\n";
}
catch(NumberFormatException e)
{
//Input was not a number. Sending proper message back to client.
returnMessage = "Please send a proper number\n";
}
//Sending the response back to the client.
OutputStream os = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(os);
BufferedWriter bw = new BufferedWriter(osw);
bw.write(returnMessage);
System.out.println("Message sent to the client is "+returnMessage);
bw.flush();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
CLIENT
public class Client
{
private static Socket socket;
public static void main(String args[])
{
Scanner input=new Scanner(System.in);
try
{
String host = "localhost";
int port = 25000;
InetAddress address = InetAddress.getByName(host);
socket = new Socket(address, port);
System.out.println("Connected to the Server");
}
catch (ConnectException exception)
{
System.out.println("Server is still offline");
}
catch(IOException ex)
{
System.out.println("Server got disconnected");
}
}
}
Well, the best way to tell if your connection is interrupted is to try to read/write from the socket. If the operation fails, then you have lost your connection sometime.
So, all you need to do is to try reading at some interval, and if the read fails try reconnecting.
The important events for you will be when a read fails - you lost connection, and when a new socket is connected - you regained connection.
That way you can keep track of up time and down time.
you can do like this
try
{
Socket s = new Socket("address",port);
DataOutputStream os = new DataOutputStream(s.getOutputStream());
DataInputStream is = new DataInputStream(s.getInputStream());
while (true)
{
os.writeBytes("GET /index.html HTTP/1.0\n\n");
is.available();
Thread.sleep(1000);
}
}
catch (IOException e)
{
System.out.println("connection probably lost");
e.printStackTrace();
}
or you can simply et connection time out like this socket.setSoTimeout(timeout); to check connectivity
or you can use
socket.getInputStream().read()
makes the thread wait for input as long as the server is connected and therefore makes your program not do anything - except if you get some input and
returns -1 if the client disconnected
or what you can do is structure your code in this way
while(isConnected())
{
// do stuffs here
}

Java Socket: Why client don't reply server

I want to write a client-sever program in which server and client send messages to each other. First, my server send a message to client, then the client reply. Next, my server send another message, the client reply. The problem is, on my first message induced by the server, the client does not respond.
My server:
public class Server {
public void go() {
try {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("Server listening ...");
Socket socket = serverSocket.accept();
try (
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String input;
printWriter.println(new Scanner(System.in).nextLine());
while ((input = bufferedReader.readLine()) != null) {
System.out.println(input);
printWriter.println(new Scanner(System.in).nextLine());
if(input == "Bye") break;
}
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.go();
}
}
My client:
public class Client {
public void go() {
try {
try (
Socket socket = new Socket("localhost", 9999);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
) {
String input;
while ((input = bufferedReader.readLine()) != null) {
System.out.println("1");
System.out.println(input);
printWriter.println(new Scanner(System.in).nextLine());
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.go();
}
}
Are there some problems with my code?
Your client connects and then blocks reading a line from the server.
Your server accepts the connection and then blocks reading a line from the client.
I don't know what you were expecting to happen next, but it won't. Somebody needs to send something.
Your code seems to be fine. You just need to push the infrastructure by calling flush() after writing:
printWriter.flush();

Creating Java Proxy MITM

I'm trying to create a Java program as a proxy to view packets from an incoming source to debug. To do this, I have created a simple Java server application and have edited my host file on the device. Everything works fine as of now, (even my Relay class file) but I am trying to make it into a full fledged proxy. How could I incorporate elements to send data to the server, and send the response back to the client? Sort of like a Man-In-The-Middle type of thing.
import java.net.*;
import java.io.*;
import org.ini4j.Ini;
public class RelayMultiClient extends Thread {
private Socket socket = null;
Socket relay = null;
public RelayMultiClient(Socket socket) {
super("RelayMultiClient");
this.socket = socket;
}
public void run() {
try {
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
if(Relay.max_clients == Relay.connected_clients) {
//There are too many clients on the server.
System.out.println("Connection refused from " + socket.getRemoteSocketAddress() + ": Too many clients connected!");
out.close();
in.close();
socket.close();
}
else {
Ini ini = new Ini(new File("settings.ini"));
Relay.connected_clients++;
System.out.println("Connection from client " + socket.getRemoteSocketAddress() + " established. Clients Connected: " + Relay.connected_clients);
while (in.readLine() != null) {
//Send data to the server
//Receive data from server and send back to client
}
System.out.println("Connection from client " + socket.getRemoteSocketAddress() + " lost.");
Relay.connected_clients--;
out.close();
in.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks,
Chris
P.S: I'm not attempting to get HTTP data, I am trying to get data from a game I have created. I don't know if this type of data requires any extra handling.
How could I incorporate elements to send data to the server, and send the response back to the client?
Try the following example as basic proxy:
public class Proxy {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(1230); // proxy port
Socket socket = serverSocket.accept();
Socket relay = new Socket("localhost", 1234); // server address
new ProxyThread(relay.getInputStream(), socket.getOutputStream()).start();
new ProxyThread(socket.getInputStream(), relay.getOutputStream()).start();
}
}
class ProxyThread extends Thread {
private InputStream inputStream;
private OutputStream outputStream;
ProxyThread(InputStream inputStream, OutputStream outputStream) {
this.inputStream = inputStream;
this.outputStream = outputStream;
}
public void run() {
try {
int i;
while ((i = inputStream.read()) != -1) {
outputStream.write(i);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
It lacks proper exception handling, only demonstrating the basic idea.

Categories