Java TCP and UDP echo in one server - java

I am trying to build a server which can echo the input from either a TCP or a UDP client.
So far the best I could come up with is this:
import java.net.*;
import java.io.*;
public class EchoServerMultiProtocol {
public static void main(String[] args) throws IOException {
String clientSentence;
String capitalizedSentence;
while (true) {
/*******************************************************************
* * Handle TCP * *
*******************************************************************/
ServerSocket TCP_Socket = new ServerSocket(6789);
Socket connectionSocket = TCP_Socket.accept();
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(
connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
/*******************************************************************
* * Handle UDP * *
*******************************************************************/
DatagramSocket UDP_Socket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
UDP_Socket.receive(receivePacket);
clientSentence = new String(receivePacket.getData());
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
capitalizedSentence = clientSentence.toUpperCase();
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, port);
UDP_Socket.send(sendPacket);
}
}
}
What happens is that if I send a message from the TCP client the program works as expected but from the UDP client nothing happens. I'm not very well versed in client/server communication so any help would be appreciated.
The client codes are below but I doubt they are the source of the problem.
TCP Client
import java.io.*;
import java.net.*;
class EchoClientTCP {
public static void main(String argv[]) throws Exception {
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
Socket clientSocket = new Socket("127.0.0.1", 6789);
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
UDP Client
import java.io.*;
import java.net.*;
class EchoClientUDP {
public static void main(String args[]) throws Exception {
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
System.in));
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("127.0.0.1");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = inFromUser.readLine();
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
Thank you for your help.

Your program blocks waiting for a TCP message, so it never sees any UDP.
You will need, at least, two threads, one for each.

Accept is a blocking call. It never gets to the part of the code with the UDP socket.

Please just make your life easy and use Netty. In a couple of lines of code you have an efficient thread model, support for most common protocols and a great framework to handle messages.

Related

Java Socket Client not Recieving Data

I have created my first test application implementing a socket server. I am having some issues getting the client to receive data, but the server gets data just fine. Here is the server:
ServerSocket socket = new ServerSocket(11111);
System.out.println("CREATING SERVER...");
while (true) {
Socket SERVER_WORK = socket.accept();
BufferedReader clientIN = new BufferedReader(new InputStreamReader(SERVER_WORK.getInputStream()));
PrintWriter outSend = new PrintWriter(SERVER_WORK.getOutputStream());
String ClientSTR = clientIN.readLine();
System.out.println("Client 1: " + ClientSTR);
String toClient = "Hello";
outSend.write(toClient + '\n');
}
And here is the client:
System.out.println("CONNECTING TO SERVER...");
while (true) {
Socket clientSocket = new Socket(server, 11111);
BufferedReader fromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream toServere = new DataOutputStream(clientSocket.getOutputStream());
Scanner in = new Scanner(System.in);
toServere.write(in.nextLine().getBytes());
if (fromServer.ready())
System.out.println(fromServer.readLine());
clientSocket.close();
}
Everything works properly except for the client receiving data.
I found the solution: I needed a '\n' at the end of the line for the DataOutputStream/PrintWriter for the BufferedReader to work properly.

Java String Equals not working for UDP server received packet

Here are simple UDP client-server classes:
UDPServer:
import java.net.*;
/**
* Source:https://systembash.com/a-simple-java-udp-server-and-udp-client/
*
*/
class UDPServer {
public static void main(String args[]) throws Exception {
DatagramSocket serverSocket = new DatagramSocket(9876);
byte[] receiveData = new byte[1024];
byte[] sendData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String(receivePacket.getData());
// Sentence here is not equal "PING" ?
if(sentence.equals("PING")) {
System.out.println("It is PING: " + sentence);
} else {
System.out.println(sentence.getClass());
System.out.println("It is not equal PING. It is <" + sentence + ">");
}
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
String capitalizedSentence = "PONG";
sendData = capitalizedSentence.getBytes();
DatagramPacket sendPacket
= new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}
}
UDPClient:
import java.net.*;
/**
* Source:
* https://systembash.com/a-simple-java-udp-server-and-udp-client/
*
* #author
*/
class UDPClient {
public static void main(String args[]) throws Exception {
DatagramSocket clientSocket = new DatagramSocket();
InetAddress IPAddress = InetAddress.getByName("localhost");
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
String sentence = "PING";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 9876);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
String modifiedSentence = new String(receivePacket.getData());
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
In the UDPServer there's a check for the response (variable sentence). For some reason the equals doesn't detect the "PING" when it has to. Moreover it outputs the sentence string is "PING", class string.
Why is that ?
The output of the UDPServer is the else:
class java.lang.String
It is not equal PING. It is:<PING>
RECEIVED: PING
If it matters the java version is "1.7.0_91".
getData() gives you a buffer from which you can obtain your data.
Don't use trim() as this could remove characters you actually want to keep (apart from being expensive)
Instead you should use the length of the message
String sentence = new String(receivePacket.getData(), 0, receivePacket.getLength());
This way you will only extract to portion of the buffer with data you want.
The getData method of DatagramPacket returns the underlying buffer, which is the 1024 byte buffer you created earlier. You create a String from this buffer. All bytes not filled in will be 0 (default initialized), so your String will contain a lot of additional zero's. That's why the equals method returns false. You could solve this with the trim method if you're sure the messages sent will not have leading or trailing whitespaces (or at least, none that matter to the rest of the program).
You are not getting true when calling equals because the response is 1024 bytes long. You can trim your response on UDPServer to solve this:
String sentence = new String(receivePacket.getData()).trim();

UDP client sending data to server, but not receiving response

I am creating a simple Android app which can communicate with my PC. On my computer I have a very simple UDP server in Java.
public void run(){
try{
DatagramSocket serverSocket = new DatagramSocket(port);
byte[] receiveData = new byte[8];
byte[] sendData = new byte[8];
while(true)
{
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
String sentence = new String( receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
String sendString = "polo";
sendData = sendString.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
serverSocket.send(sendPacket);
}
}catch (Exception e){
}
}
and I have another simple piece of code inside my android app which sends a UDP packet to the server and awaits the response.
public void checkServerOnline(View v) {
try {
int port = 46001;
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.setSoTimeout(1800);
InetAddress IPAddress = InetAddress.getByName(host);
byte[] sendData = new byte[8];
byte[] receiveData = new byte[8];
String sentence = "marco";
sendData = sentence.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, port);
clientSocket.send(sendPacket);
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
clientSocket.close();
} catch (Exception e) {
}
The problem I am having is that my Client is timing out waiting for a response. The server is definitely receiving the string "marco" and is presumably sending the response "polo", but the client is not receiving it. I've tried removing the timeout on the client, but it just freezes up until I force close the application.
Can anyone see an error in my code? I can't understand why it won't work. I've managed to successfully setup a TCP Server and client with the same setup, but cannot seem to do UDP.
The server is sending to the wrong port. It should send to the port in the received datagram, not its own port. It is simplest to reuse the request datagram and just change the data to the response data: the return address is already there.

how to implement TCP server and TCP client in java to transfer files

I have implement the simple TCP server and TCP client classes which can send the message from client to server and the message will be converted to upper case on the server side, but how can I achieve transfer files from server to client and upload files from client to server. the following codes are what I have got.
TCPClient.java:
import java.io.*;
import java.net.*;
class TCPClient {
public static void main(String args[]) throws Exception {
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
Socket clientSocket = new Socket("127.0.0.1", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + "\n");
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER:" + modifiedSentence);
clientSocket.close();
}
}
TCPServer.java:
import java.io.*;
import java.net.*;
class TCPServer {
public static void main(String args[]) throws Exception {
int firsttime = 1;
while (true) {
String clientSentence;
String capitalizedSentence="";
ServerSocket welcomeSocket = new ServerSocket(3248);
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
//System.out.println(clientSentence);
if (clientSentence.equals("set")) {
outToClient.writeBytes("connection is ");
System.out.println("running here");
//welcomeSocket.close();
//outToClient.writeBytes(capitalizedSentence);
}
capitalizedSentence = clientSentence.toUpperCase() + "\n";
//if(!clientSentence.equals("quit"))
outToClient.writeBytes(capitalizedSentence+"enter the message or command: ");
System.out.println("passed");
//outToClient.writeBytes("enter the message or command: ");
welcomeSocket.close();
System.out.println("connection terminated");
}
}
}
So, the TCPServer.java will be executed first, and then execute the TCPClient.java, and I try to use the if clause in the TCPServer.java to test what is user's input,now I really want to implement how to transfer files from both side(download and upload).Thanks.
So lets assume on server side you have received the file name and file path. This code should give you some idea.
SERVER
PrintStream out = new PrintStream(socket.getOutputStream(), true);
FileInputStream requestedfile = new FileInputStream(completeFilePath);
byte[] buffer = new byte[1];
out.println("Content-Length: "+new File(completeFilePath).length()); // for the client to receive file
while((requestedfile.read(buffer)!=-1)){
out.write(buffer);
out.flush();
out.close();
}
requestedfile.close();
CLIENT
DataInputStream in = new DataInputStream(socket.getInputStream());
int size = Integer.parseInt(in.readLine().split(": ")[1]);
byte[] item = new byte[size];
for(int i = 0; i < size; i++)
item[i] = in.readByte();
FileOutputStream requestedfile = new FileOutputStream(new File(fileName));
BufferedOutputStream bos = new BufferedOutputStream(requestedfile);
bos.write(item);
bos.close();
fos.close();
Assuming you want to continue to support sending messages as well as sending files back and forth...
As you have now, you are using writeBytes to send data from client to server.
You can use that to send anything, like the contents of files...
But you will need to define a protocol between your client and server so that they know when a file is being transferred rather than a chat message.
For example you could send the message/string "FILECOMING" before sending a file to the server and it would then know to expecting the bytes for a file. Similarly you'd need a way to mark the end of a file too...
Alternatively, you could send a message type before each message.
A more performant/responsive solution is to do the file transfer on a separate thread/socket - this means that the chat messages are not held up by the transfers. Whenever a file transfer is required, a new thread/socket connection is created just for that.
~chris
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String argv[]) throws IOException
{
String sentence;
String modifiedSentence;
Socket clientSocket = new Socket("*localhost*", *portnum*); // new Socket("192.168.1.100", 80);
System.out.println("Enter your ASCII code here");
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
sentence = inFromUser.readLine();
// System.out.println(sentence);
while(!(sentence.isEmpty()))
{
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes(sentence);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
modifiedSentence = inFromServer.readLine();
while(!(modifiedSentence.isEmpty()))
{
System.out.println("FROM SERVER: " + modifiedSentence);
break;
}
System.out.println("Enter your ASCII code here");
inFromUser = new BufferedReader( new InputStreamReader(System.in));
sentence = inFromUser.readLine();
}
System.out.println("socket connection going to be close");
clientSocket.close();
}
}

Read the packets of bytes on client socket from server socket for connection oriented (TCP) client/server? [duplicate]

This question already has an answer here:
to read the packet of bytes on client(client Socket) from server(ServerSocket) using java
(1 answer)
Closed 7 years ago.
i m creating connection oriented server/client(TCP) socket.i have created whole server socket and i have written packet on server socket successfully and i have created client socket also but i m not be able to read packet so please give me the idea about read the packet(code or example) on client socket and tell clearly that can i read a packet on client socket or not if no then what should use in place of client and server socket
You don't generally read a packet at a time - you read from the InputStream returned by Socket.getInputStream(). You should almost certainly be treating the connection as a stream, rather than even attempting to handle individual packets.
If you still run into problems, it would really help if you could post some code to show how you're connecting the socket etc.
I had to implement such a thing for my networking course in college.
Here's an excerpt from the book
TCPServer.java
import java.io.*;
import java.net.*;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
String clientSentence;
String capitalizedSentence;
ServerSocket welcomeSocket = new ServerSocket(6789);
while(true)
{
Socket connectionSocket = welcomeSocket.accept();
BufferedReader inFromClient =
new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println("Received: " + clientSentence);
capitalizedSentence = clientSentence.toUpperCase() + '\n';
outToClient.writeBytes(capitalizedSentence);
}
}
}
TCPClient.java
import java.io.*;
import java.net.*;
class TCPClient
{
public static void main(String argv[]) throws Exception
{
String sentence;
String modifiedSentence;
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket("localhost", 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
sentence = inFromUser.readLine();
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
}
Hopefully this will be sufficient to figure out what you did wrong. Good luck!

Categories