Java socket write issues - java

I am trying to create a Modbus setup as follows:
client <----> IED <----> Modbus Server
IED has the IP 192.168.x.x and Modbus Server uses localhost as IP. All entities are in the same VM. The client is supposed to send a request to the IED,the IED forwards it to the server and the server responds to the IED.
The problem is the IED receives the request from the master which is stored in a byte array but transmitting the request to the server does not work. Wireshark traces show that the TCP connection is established with the server but request is not transmitted.
See the code below:
public class App {
public static void main(String[] args) {
IEDServer iedServer = new IEDServer();
iedServer.start(502);
}
}
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
public class IEDServer {
private ServerSocket serverSocket;
public void start (int port){
try {
InetAddress inetAddress = InetAddress.getByName("192.168.20.138");
serverSocket = new ServerSocket(port, 1024, inetAddress);
while (true){
new ClientHandler(serverSocket.accept()).start();
System.out.println("Connection accepted");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void stop(){
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.*;
import java.net.Socket;
public class ClientHandler extends Thread{
private Socket clientSocket;
private DataOutputStream out;
private DataInputStream in;
public ClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
try {
//connection from client
out = new DataOutputStream (clientSocket.getOutputStream());
in = new DataInputStream(clientSocket.getInputStream());
// in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// String readline;
//for connection to modbus server
Socket modbusSocket = new Socket("127.0.0.1",502);
modbusSocket.setSoTimeout(10000);
DataOutputStream modbus_out = new DataOutputStream (clientSocket.getOutputStream());
DataInputStream modbus_in = new DataInputStream(clientSocket.getInputStream());
byte [] modbus_bytes = {};
//read Modbus bytes from client to get client request
modbus_bytes = in.readAllBytes();
System.out.println("Modbus request: ");
for (byte b: modbus_bytes){
System.out.print(b);
}
System.out.println();
//transfer modbus request to modbus server
modbus_out.write(modbus_bytes, 0, modbus_bytes.length);
//get response from modbus server
modbus_bytes = modbus_in.readAllBytes();
System.out.println("Modbus response: ");
for (byte b: modbus_bytes){
System.out.print(b);
}
System.out.println();
//transfer response to client
out.write(modbus_bytes,0,modbus_bytes.length);
} catch (IOException e) {
e.printStackTrace();
}
//close TCP connection
try {
in.close();
out.close();
clientSocket.close();
System.out.println("Connection terminated");
} catch (IOException e) {
e.printStackTrace();
System.out.println("Connection termination failed");
}
}
}
Also find below, the wireshark screenshot

Call DataOutputStream.flush() after DataOutputStream.write() to force the bytes to be send

I managed to fix it. I mistakenly passed clientSocketinstead of modbusSocketas a parameter to the modbus_inand modbus_outStream instances. I also had to poll for availability of data before reading and then writing. Also, I noticed that the client-side closed the TCP session while the server-side had it open. So I ensured that the connection was closed after each query.
Please find modified code below for ClientHandler:
import java.io.*;
import java.net.Socket;
public class ClientHandler extends Thread {
private Socket clientSocket;
private Socket modbusSocket;
private DataOutputStream out, modbus_out;
private DataInputStream in, modbus_in;
public ClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
System.out.println(clientSocket.getInetAddress());
try {
out = new DataOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
in = new DataInputStream(new BufferedInputStream(clientSocket.getInputStream()));
// in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// String readline;
//for connection to modbus server
modbusSocket = new Socket("127.0.0.1", 502);
// modbusSocket.setSoTimeout(10000);
modbus_out = new DataOutputStream(new BufferedOutputStream(modbusSocket.getOutputStream()));
modbus_in = new DataInputStream(new BufferedInputStream(modbusSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void run() {
try {
//connection from client
if (in.available() > 0) {
//read Modbus bytes from client to get client request
System.out.println("===============Begin reading===============");
byte[] modbus_bytes = new byte[in.available()];
in.read(modbus_bytes);
System.out.println("Modbus request: ");
for (byte b : modbus_bytes) {
System.out.print(b);
}
System.out.println();
//transfer modbus request to modbus server
modbus_out.write(modbus_bytes);
modbus_out.flush();
System.out.println("Written to modbus server");
while (modbus_in.available() == 0) {
System.out.println("Waiting for device response...");
}
System.out.println("\nDevice response ready");
//get response from modbus server
modbus_bytes = new byte[modbus_in.available()];
modbus_in.read(modbus_bytes);
System.out.print("Modbus response: ");
for (byte b : modbus_bytes) {
System.out.print(b);
}
System.out.println("\nSending response to client");
//transfer response to client
out.write(modbus_bytes);
out.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
//close TCP connection
try {
// in.close();
// out.close();
clientSocket.close();
modbusSocket.close();
System.out.println("===========Connection terminated==============");
} catch (IOException e) {
e.printStackTrace();
System.out.println("Connection termination failed");
}
}
}

Related

Sending a Message to Multiple Clients from One Server Simultaneously?

I am currently working on a TCP Sockets program in Java in which two or more separate clients connect to a single server, and that server will send a message to both of these connected clients simultaneously.
I've tried to work through the code multiple times, but I can't quite seem to be able to have one message be sent to both clients.
Below is a reduced version of my entire code, condensed down to just the issue I'm having.
I've also included a video, just to save you the effort of having to copy and run my code!
[STREAMABLE LINK]
When one client is connected, I just have to write one message in the server, press send, and it shows up in the client.
When two clients are connected, I have to write two messages in the server and press send twice, and one message goes to one client and the other to the next client.
How can I make it so I only send one message from the server that goes to all clients?
I greatly appreciate any and all help.
SERVER CODE:
import java.io.*;
import java.net.*;
import java.util.*;
// Server class
class Server {
public class countLogic {
public static int client_count = 0;
}
public static void main(String[] args) {
System.out.println("[SERVER]");
ServerSocket server = null;
try {
server = new ServerSocket(1234);
server.setReuseAddress(true);
while (true) {
Socket client = server.accept();
countLogic.client_count++;
System.out.println("Client ("+countLogic.client_count+") connected: " + client.getInetAddress().getHostAddress());
ClientHandler clientSock = new ClientHandler(client);
new Thread(clientSock).start();
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
if (server != null) {
try {
server.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
// ClientHandler class
private static class ClientHandler implements Runnable {
private final Socket clientSocket;
public ClientHandler(Socket socket)
{
this.clientSocket = socket;
}
public void run()
{
PrintWriter out = null;
BufferedReader in = null;
try {
Scanner sc = new Scanner(System.in);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String line = null;
while (true) {
line = sc.nextLine();
out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
clientSocket.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
CLIENT CODE:
import java.io.*;
import java.net.*;
import java.util.*;
// Client class
class Client {
// driver code
public static void main(String[] args)
{
System.out.println("[CLIENT 1]");
try (Socket socket = new Socket("localhost", 1234)) {
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Scanner sc = new Scanner(System.in);
String line = null;
while (!"exit".equalsIgnoreCase(line)) {
System.out.println("Server: "+ in.readLine());
}
// closing the scanner object
sc.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}

Java Threaded Server Client Messaging Application

I'm trying to make a threaded server client messaging application in java. I'm having trouble sending a message that a client sent to every other client connected to the server. I added all connected threads to an array list so when a message is sent I can iterate over the list and send it to all the clients but this doesn't seem to be working. What am I doing wrong here?
When one client is connected it works perfectly the server echos everything the client says. When two clients are connected only the client that sent the message gets the message. If that same client though send another message the server seems to get hung up and no messages get echoed.
Threaded Server Code
import java.io.*;
import java.net.*;
import java.util.*;
public class ThreadedSever
{
private static final int port=5000;
ArrayList<ServerThread> clientList = new ArrayList<ServerThread>();
//Threaded Server
public ThreadedSever(){
System.out.println("A multi-threaded server has started...");
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
}catch(Exception e){
System.out.println("Could not create a server socket: " + e);
}
//Chat with the client until breaks connection or says bye
try{
while(true){
System.out.println("Waiting for client communication");
Socket currentSocket = serverSocket.accept();
//Create a new thread to deal with this connection
clientList.add(new ServerThread(currentSocket));
System.out.println(clientList);
}
}catch(Exception e){
System.out.println("Fatal Server Error!");
}
}
//Inner class to handle individual commincation
private class ServerThread extends Thread{
//Possible add name to then get private messages
private Socket sock;
private DataInputStream in = null;
private DataOutputStream out = null;
public ServerThread(Socket sock){
try{
this.sock = sock;
in = new DataInputStream(this.sock.getInputStream());
out = new DataOutputStream(this.sock.getOutputStream());
System.out.print("New client connection established");
out.writeUTF("Type bye to exit, otherwise, prepare to be echoed");
start();
}catch(Exception e){
System.out.println("Oops");
}
}
public void run(){
try{
String what = new String("");
while(!what.toLowerCase().equals("bye")){
what = in.readUTF();
echoMessage(what);
}
}catch(Exception e){
System.out.println("Connection to current client has been broken");
}
finally{
try{
sock.close();
}catch(Exception e){
System.out.println("Error socket could not be closed");
}
}
}
public void echoMessage(String what){
try{
for (ServerThread Thread: clientList) {
in = Thread.in;
out = Thread.out;
System.out.println("Client told me: " + what);
out.writeUTF(what);
}
}catch(Exception e){
}
}
}
public static void main(){
new ThreadedSever();
}
}
Client Code
import java.io.*;
import java.net.*;
public class simpleClient
{
private static final int port= 5000;
private static String server = "localhost";
private static Socket socket = null;
private static DataInputStream input = null;
private static DataOutputStream output = null;
private static InputStreamReader inReader = null;
private static BufferedReader stdin = null;
public static void main(){
try{
socket = new Socket(server, port);
}catch(UnknownHostException e){
System.err.println("Unknow IP address for server");
System.exit(-1);
}
catch(IOException e){
System.err.println("No server found at specified port");
System.exit(-1);
}
catch(Exception e){
System.err.println("Something happened!");
System.exit(-1);
}
try{
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
inReader = new InputStreamReader(System.in);
stdin = new BufferedReader(inReader);
String what = new String("");
String response;
while(!what.toLowerCase().equals("bye")){
// Expect something from the server and output it when it arrives
response = input.readUTF();
System.out.println("Server said \"" + response + "\"");
//Read a line from the user and send it to the server
what = stdin.readLine();
output.writeUTF(what);
}
}
catch(IOException e){
System.err.println("Broken connection with server");
System.exit(-1);
}
}
}

Java client/server chat [duplicate]

This question already has an answer here:
no output for java client/server app [closed]
(1 answer)
Closed 5 years ago.
I've got a problem with my simple TCP/IP chat. It seems that my server doesn't receive messages from connected clients and I have no idea why it is happening.
Server code:
public class ChatServer {
public static final int MAX_CLIENTS = 10;
public static final ClientHandler[] clients = new ClientHandler[MAX_CLIENTS];
public void go(int port){
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("Connection established on port "+port);
System.out.println("Waiting for clients...");
while (true){
Socket clientSocket = serverSocket.accept();
for (int i=0; i<clients.length;i++){
if (clients[i]==null){
ClientHandler clientHandler = new ClientHandler(clientSocket, clients);
clients[i] = clientHandler;
System.out.println("Added new client!");
clientHandler.start();
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientHandler class:
public class ClientHandler extends Thread {
private Socket socket;
private ClientHandler[] clients;
private PrintWriter out;
public ClientHandler(Socket clientSocket, ClientHandler[] clientsThreads){
socket = clientSocket;
clients = clientsThreads;
}
#Override
public void run() {
ClientHandler[] threads = this.clients;
try {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
for (int i=0; i<threads.length;i++){
if (threads[i]!=null){
threads[i].out.println("***SERVER: New client entered the chat room!***");
}
}
while (true){
System.out.println("in while loop - reading and writing to the client socket");
String inputLine = in.readLine();
System.out.println(inputLine);
if (inputLine.startsWith("/quit")){
break;
}
for (int i=0; i<threads.length;i++){
if (threads[i]!=null){
threads[i].out.println(inputLine);
}
}
}
System.out.println("One of the clients is leaving the chat room");
for (int i=0; i<threads.length;i++){
if (threads[i]==this){
threads[i]=null;
}
}
out.close();
in.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And the client code:
public class ChatClient {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private BufferedReader stdLine;
private boolean closed = false;
public void go(String hostName, int port){
try {
initializeResource(hostName, port);
new Thread(new ServerReader()).start();
while (!closed){
out.println(stdLine.readLine().trim());
}
in.close();
out.close();
socket.close();
System.out.println("Goodbye!");
} catch (IOException e) {
e.printStackTrace();
System.out.println("Failed to connect, please try again.");
}
}
public void initializeResource(String hostName, int port) throws IOException {
socket = new Socket(hostName, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream());
stdLine = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Connection established!");
}
public class ServerReader implements Runnable{
#Override
public void run() {
String inputLine = null;
try {
while ((inputLine=in.readLine())!=null){
System.out.println(inputLine);
if (inputLine.startsWith("Bye!")){
closed = true;
return;
}
}
in.close();
out.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The result of running these applications for server:
Connection established on port 8000
Waiting for clients...
Added new client!
in while loop - reading and writing to the client socket
And for client:
Connection established!
***SERVER: New client entered the chat room!***
In the client version I can write messages in the terminal all the time, but none of these messages isn't received by the server (otherwise messages would be written in the server's terminal). I will appreciate any suggestion.
You need to flush after printing a line from the client:
while (!closed){
out.println(stdLine.readLine().trim());
out.flush();
}

Broadcasting to multiple clients using TCP connection in Java

I am trying to broadcast a message to multiple clients but could not do so. I tried saving the socket connections in an array list and using a for loop, i tried to broadcast the message but only the client who posted the message is receiving the reply from server.
Client Code:
import java.net.*;
import java.util.Scanner;
import org.json.simple.JSONObject;
import java.io.*;
public class TCPClient {
public static void main (String args[]) {
// arguments supply message and hostname
JSONObject clientObj=new JSONObject();
Socket s = null;
try{
int serverPort = 7899;
Scanner scan=new Scanner(System.in);
s = new Socket("127.0.0.1", serverPort);
System.out.println("Connection Established");
DataInputStream in = new DataInputStream( s.getInputStream());
DataOutputStream out =new DataOutputStream( s.getOutputStream());
while(true)
{
System.out.print(">");
String inputdata=scan.nextLine();
clientObj.put("ID",inputdata );
System.out.println("Sending data");
out.writeUTF(clientObj.toString()); // UTF is a string encoding see Sn. 4.4
String data = in.readUTF(); // read a line of data from the stream
System.out.println(data) ; //writing received data
}
}catch (UnknownHostException e) {
System.out.println("Socket:"+e.getMessage());
}catch (EOFException e){
System.out.println("EOF:"+e.getMessage());
}catch (IOException e){
System.out.println("readline:"+e.getMessage());
}finally {
if(s!=null) try {
s.close();
}catch (IOException e){
System.out.println("close:"+e.getMessage());
}
}
}
}
Server Code:
import java.net.*;
import java.util.ArrayList;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.*;
public class TCPServer {
static ArrayList<String> client=new ArrayList<String>();
static ArrayList<Socket> clientSock=new ArrayList<Socket>();
static int i = 0;
public static void main (String args[]) {
try{
int serverPort = 7899; // the server port
ServerSocket listenSocket = new ServerSocket(serverPort);
while(true) {
System.out.println("Server listening for a connection");
Socket clientSocket = listenSocket.accept();
i++;
System.out.println("Received connection " + i );
Connection c = new Connection(clientSocket);
client.add("guest"+i);
clientSock.add(clientSocket);
}
}
catch(IOException e)
{
System.out.println("Listen socket:"+e.getMessage());
}
}
public void display(String BroadMsg1)
{
for(int j=0;j<client.size();j++)
{
System.out.println(clientSock.get(j));
}
}
public void broadcast(String BroadMsg)
{
String clientName=null;
Socket cSock=null;
//DataInputStream inBroad;
DataOutputStream outBroad=null;
for(int j=0;j<client.size();j++)
{
clientName=client.get(j);
cSock=clientSock.get(j);
try{
outBroad=new DataOutputStream(cSock.getOutputStream());
outBroad.writeUTF(clientName+">"+BroadMsg);
}catch(Exception ex)
{
/*client.remove(j);
clientSock.remove(j);*/
System.out.println(ex.getMessage());
}
}
}
}
class Connection extends Thread {
TCPServer tcpser=new TCPServer();
DataInputStream in;
DataOutputStream out;
Socket clientSocket;
public Connection (Socket aClientSocket) {
try {
clientSocket = aClientSocket;
in = new DataInputStream( clientSocket.getInputStream());
out =new DataOutputStream( clientSocket.getOutputStream());
this.start();
} catch(IOException e) {
System.out.println("Connection:"+e.getMessage());
}
}
public void run(){
JSONObject serObj=new JSONObject();
JSONParser jParser=new JSONParser();
try { // an echo server
while(true)
{
System.out.println("server reading data");
String data = in.readUTF(); // read a line of data from the stream
try {
serObj=(JSONObject)jParser.parse(data); //parsing JSONObject
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println("server writing data");
// tcpser.display(serObj.get("ID").toString());
tcpser.broadcast(serObj.get("ID").toString());
}}
catch (EOFException e){
System.out.println("EOF:"+e.getMessage());
} catch(IOException e) {
System.out.println("readline:"+e.getMessage());
} finally{
try {
clientSocket.close();
}catch (IOException e){/*close failed*/}
}
}
}
Can anyone please help me out to rectify the mistake.
Thanks in advance :)
After creating Client Socket with accept command in server, start a new Thread by passing this socket is parameter. In the new thread, open InputStream and process it.
Go through the list of all client sockets and send the message by opening OutputStream on respective socket
Have look at this example Socket Programming. You can look at java docs for alternative approach Broadcasting
1) Create client thread after adding to the list.
2)Print Exception stack trace in catch block to know exception.
3) replace cSock=clientSock.get(j); with Iterator to go through all sockets.

Java UDP server

I am new to Java programming and I am trying to create a UDP server. When I compile the code it says it could not listen to port 4722 and I would like to know why. Below is the code. I would be grateful for any advice.
import java.net.*;
import java.io.*;
public class Server
{
public static void main(String[] args) throws IOException
{
DatagramSocket serverSocket = new DatagramSocket(4722);
Socket clientSocket = null;
byte[] receiveData = new byte[1024];
byte[] sendData = new byte [1024];
boolean command = true;
try
{
serverSocket = new DatagramSocket(4722);
DatagramPacket receivePacket = new DatagramPacket(receiveData,receiveData.length);
System.out.println("Waiting for client...");
}
catch (IOException e)
{
System.err.println("Could not listen on port: 4722.");
System.exit(1);
}
DatagramPacket packet = new DatagramPacket (sendData,sendData.length,4722);
serverSocket.send(packet);
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String inputLine, outputLine;
mathematicalProtocol bbm = new mathematicalProtocol();
outputLine = bbm.processInput(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null)
{
if(inputLine.equals("Bye."))
break;
outputLine = bbm.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
You are initializing serverSocket and then making a new DatagramSocket on the same port again (and you can't do that as it's already bound on the first DatagramSocket). I.e. remove the following line:
serverSocket = new DatagramSocket(4722);
Here is a complete example of client/server UDP communication.
The server read data from a file and send each line to the client.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* #author nono
*
*/
public class UDPFileSender {
static class Client implements Runnable {
// Reception socket
private DatagramSocket socket;
// UDP packet to receive data into
private DatagramPacket packet;
// Flag for initialisation
private boolean failedInit = true;
/**
* Client constructor.
* #param receptionPort
* #param packetMaxLenght
*/
public Client(int receptionPort, int packetMaxLenght) {
try {
// Create the socket using the reception port
this.socket = new DatagramSocket(receptionPort);
// Init the packet
this.packet = new DatagramPacket(new byte[packetMaxLenght],packetMaxLenght);
this.failedInit = false;
} catch (SocketException e) {
//Port already used or other error
e.printStackTrace();
}
}
#Override
public void run() {
if(failedInit){
return;
}
// Loop undefinitly
while(true){
try {
System.out.println("Waiting for packet...");
// Wait for packet
socket.receive(packet);
// Assuming you are receiving string
String msg = new String(packet.getData());
System.out.println("Received : " + msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
try {
int port = 4722;
//Start a client that can listen
new Thread(new Client(port,1024)).start();
// Creaete a reader
BufferedReader reader = new BufferedReader(new FileReader("File.txt"));
//Create a socket
DatagramSocket socket = new DatagramSocket();
// Create a packet
byte[] data = new byte[1024]; // Max length
DatagramPacket packet = new DatagramPacket(data, data.length);
// Set the destination host and port
packet.setAddress(InetAddress.getByName("localhost"));
packet.setPort(port);
String line = null;
while((line = reader.readLine()) != null){
//Set the data
packet.setData(line.getBytes());
//Send the packet using the socket
System.out.println("Sending : " + line);
socket.send(packet);
Thread.sleep(200);
}
//Close socket and file
reader.close();
socket.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
If your file contains :
Hello
World
You should see :
Waiting for packet...
Sending : Hello
Received : HelloWaiting for packet...
Sending : World
Received : World
Waiting for packet...

Categories

Resources