I'm trying to socket connection between a Ruby Server and a Java Client. The connection is setup with success but I'm finding difficulties when sending a message from server to client.
This is how my Ruby Server looks like:
class ServerSocket
loop do
server = TCPServer.new(ip, port).accept
while server
line = server.recv(65000)
puts "Message: #{line}"
server.flush
server.puts("Hi from server!")
server.flush
end
end
end
When I try with this Java Client:
Socket socket = new Socket(InetAddress.getByName(ip), port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.write("Hello from client!");
socket.close();
the connection is established and the message is sent with success from client to server. But when the server reaches this line:
server.puts("Hi from server!")
it throws this exception:
lib/server_socket.rb:11:in `write': Broken pipe (Errno::EPIPE)
from lib/server_socket.rb:11:in `puts'
from lib/server_socket.rb:11:in `block in <class:ServerSocket>'
from lib/server_socket.rb:2:in `loop'
from lib/server_socket.rb:2:in `<class:ServerSocket>'
from lib/server_socket.rb:1:in `<top (required)>'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/railties-5.1.4/lib/rails/commands/runner/runner_command.rb:34:in `load'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/railties-5.1.4/lib/rails/commands/runner/runner_command.rb:34:in `perform'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/thor-0.20.0/lib/thor/command.rb:27:in `run'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/thor-0.20.0/lib/thor/invocation.rb:126:in `invoke_command'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/thor-0.20.0/lib/thor.rb:387:in `dispatch'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/railties-5.1.4/lib/rails/command/base.rb:63:in `perform'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/railties-5.1.4/lib/rails/command.rb:44:in `invoke'
from /home/dionis/.rvm/gems/ruby-2.4.1#sample/gems/railties-5.1.4/lib/rails/commands.rb:16:in `<top (required)>'
from bin/rails:9:in `require'
from bin/rails:9:in `<main>'
Another user experience is when I try with this Java Client:
Socket socket = new Socket(InetAddress.getByName(ip), port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.write("Hello from client!");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String serverMsg = in.readLine();
System.out.println("Server: " + serverMsg);
socket.close();
Here, I'm trying to get the message from the server. But when the client reaches this line:
String serverMsg = in.readLine();
it just hangs there forever.
Does anyone know how to deal with this?
EDIT (full client code)
ClientSocket.java
public class ClientSocket implements Runnable{
#Override
public void run() {
System.out.println("Connecting...");
try {
Socket socket = new Socket(InetAddress.getByName(ip), port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.write("Hello from client!");
socket.close();
System.out.println("Closing...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Main.java
public class Main{
public static void main(String[] args) {
Thread cThread = new Thread(new ClientSocket());
cThread.start();
}
}
#Dionis I am not familiar with java.
Have written a java client and ruby server I guess this will help you.
Ruby TCP server code:
require 'socket'
server = TCPServer.new(12345).accept
line = server.recv(50)
puts "Message from java Client: #{line}"
server.flush
server.puts("Hi from server!")
server.flush
Java TCP Client code:
import java.net.*;
import java.io.*;
class Main{
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 12345);
DataInputStream is = new DataInputStream(socket.getInputStream());
DataOutputStream os = new DataOutputStream(socket.getOutputStream());
os.writeBytes("Hello \n");
String line = is.readLine();
System.out.println("Msg from ruby Server :" + line);
socket.close();
}
}
Let me know if resolve the issue
Thanks!
Related
Hello stackoverflow community,
i am stuck at a problem regarding socket communication in Java.
Here is the sample code of my Server and Client class:
Server:
public class OTPServer {
static ServerSocket serverSocket;
final static int PORT = 4242;
static Socket clientConnection;
public static void main(String[] args) {
try {
serverSocket = new ServerSocket(PORT);
System.out.println("Socket initialized");
String serverMessage = "Hello, I am the Host";
ServerTool serverTool = new ServerTool();
while (true) {
clientConnection = serverSocket.accept();
if(clientConnection.isConnected()) {
System.out.println("Client connected");
}
BufferedReader clientInputReader = new BufferedReader(new InputStreamReader(clientConnection.getInputStream()));
DataOutputStream serverOutput = new DataOutputStream(clientConnection.getOutputStream());
System.out.println("Sending message to client: " + serverMessage);
serverOutput.writeBytes(serverTool.encodeMessage(serverMessage));
serverOutput.flush();
String clientMessage = clientInputReader.readLine();
System.out.println("Encoded answer from client: " + clientMessage);
String decodedMessage = serverTool.decodeMessage(clientMessage);
System.out.println("Decoded answer from client: " + decodedMessage);
serverOutput.close();
clientInputReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Hello, I am the OTP Server!");
}
Here is the Client:
public class OTPClient {
static Socket clientSocket;
final static int PORT = 4242;
final static String HOST = "localhost";
public static void main(String[] args) {
System.out.println("I am the OTP Client!");
String serverMessage;
String clientResponse = "I am the Client";
OTPTool otpTool = new OTPTool();
try {
clientSocket = new Socket(HOST, PORT);
BufferedReader serverInput = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
DataOutputStream outputStream = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("Connection to Host established");
serverMessage = serverInput.readLine();
System.out.println("Encoded Message from Server: " + serverMessage);
String decodedMessage = otpTool.decodeMessage(serverMessage);
System.out.println("Decoded message from Server: " + decodedMessage);
System.out.println("Answering with own message: " + clientResponse);
outputStream.writeBytes(clientResponse);
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Now where is my problem:
The connection establishes and the Server seems to send its message to the client and waits for a answer. The Client does not print the message he got from the Server.
As soon as i cancel the Server the client prints the message it gets from the server as well as the information, that the answer is send end exits with exit code 0 so it seems that this part is fine it just is stuck somehow.
I already tried to flush the outputStream as you see in the example code given.
Is there something obvious im missing?
I know, this is really basic stuff but its my first time using sockets for communication.
Thank you in advance!
Best Regards,
Ronny
Btw: i know that the server only connects to one client requesting a connection. Thats absolutely sufficient for my use.
It is getting stuck because serverInput.readLine(); blocks until either a line break or end of file is encountered. On the server side, you are not sending a line break, so the client blocks.
Hello programmers on the internet. I am currently stepping through an operating systems book and there are some exercises that involve the following pieces of code.
This is the server code
import java.net.*;
import java.io.*;
public class DateServer{
public static void main(String[] args) {
try {
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true) {
Socket client = sock.accept();
PrintWriter pout = new
PrintWriter(client.getOutputStream(), true);
// write the Date to the socket
pout.println(new java.util.Date().toString());
// close the socket and resume
// listening for connections
client.close();
}
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
This is the client code
import java.net.*;
import java.io.*;
public class DateClient{
public static void main(String[] args) {
try {
//make connection to server socket
Socket sock = new Socket("127.0.0.1",6013);
InputStream in = sock.getInputStream();
BufferedReader bin = new
BufferedReader(new InputStreamReader(in));
// read the date from the socket
String line;
while ( (line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
sock.close();
}
catch (IOException ioe) {
System.err.println(ioe);
}
}
}
So to my understanding the server is creating a socket and writing a date value to it. The client is then coming a long and connecting to the server and writing out the value in that socket. Am I interpreting this code correctly? This is my first experience with sockets.
Now for my actual question. I want to have the client connect to the server (and print out a message saying you are connected) and then be able to send a value over to the server so that the server can process it. How would I go about doing this? I have tried tinkering with DataOutputStream and DataInputStream but I have never used either before. Any help would be GREATLY appreciated.
You are correct. You have the server writing to the socket and the client reading from the socket. You want to reverse that.
Server Should look like:
ServerSocket sock = new ServerSocket(6013);
// now listen for connections
while (true)
{
Socket client = sock.accept();
InputStream in = client.getInputStream();
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
// read the date from the client socket
String line;
while ((line = bin.readLine()) != null)
System.out.println(line);
// close the socket connection
client.close();
}
The client should look like:
try
{
// make connection to server socket
Socket sock = new Socket("127.0.0.1", 6013);
PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
// send a date to the server
out.println("1985");
sock.close();
}
catch (IOException ioe)
{
System.err.println(ioe);
}
Recently I was looking at socket communications, and after I read few tutorials I came out with something like that.
public class Server{
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket server = new ServerSocket(9999);
Socket socket = server.accept();
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String message = "";
int ch = -1;
while((ch=in.read())!= -1 ){
message+=ch;
}
// String message = in.readLine();
System.out.println("RECEIVED "+message);
out.write("RESPONSE "+message+"\n");
out.flush();
System.out.println("NEW MESSAGE SEND");
Thread.sleep(3000);
System.out.println("CLOSE");
server.close();
}
}
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 9999);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.write("MESSAGE\n");
out.flush();
System.out.println("SEND MESSAGE");
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
System.out.println(in.readLine());
socket.close();
}
}
After I run this code, Client logs "SEND MESSAGE" while server hangs on in.read() and does not receiving any message.
Can anyone help me and explain me what I'm doing wrong?
Your server is reading from the socket until end of stream. End of stream only occurs when the peer closes the connection. At that point you will be unable to send a reply. You need to reconsider your protocol. For a simple example you could read and write lines, one at a time, as you are in the client.
I have been trying to send a simple string between a Java client socket and a Python server socket. This is the code for the server socket:
HOST=''
PORT=12000
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADRR,1)
s.bind((HOST,PORT))
s.listen(5)
device=variador()
while True:
conn,addr=s.accept()
if data=="turn_on":
respuesta=device.send_order(variador.start_order)
conn.send(respuesta+'\n')
conn.close()
and the client code is:
try {
Socket socket = new Socket("192.168.10.171", 12000);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
out.print(command);
out.close();
in.close();
socket.close();
} catch (UnknownHostException e) {
System.err.println("Unknown Host.");
// System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection.");
// System.exit(1);
}
Everything works fine until I try to read the server's response, using this:
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
then the code hangs and the Python server does not receive any information, which I tested using print.
Is there a problem trying to send first and then wait for a response from the server in the Java client?
Any help will be much appreciated.
Well, I discovered that the Java client hangs because the messages sent by the python server were not explicitly finished with \r\n, so the Python code should have been something like this:
HOST = ''
PORT = 12000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADRR, 1)
s.bind((HOST, PORT))
s.listen(5)
device = variador()
while True:
conn, addr = s.accept()
if data == "turn_on\r\n":
respuesta = device.send_order(variador.start_order)
conn.send(respuesta + '\r\n')
conn.close()
I know it should have been quite obvious from the name of the methods in Java, readline() and println, both suggesting that java ends strings with the sequence \r\n
Connect Python And Java Sockets
Install the package jpysocket
pip install jpysocket
https://pypi.org/project/jpysocket
Import Library jpysocket
The Followings Are The Some Example
Python Server :
import jpysocket
import socket
host='localhost' #Host Name
port=12345 #Port Number
s=socket.socket() #Create Socket
s.bind((host,port)) #Bind Port And Host
s.listen(5) #Socket is Listening
print("Socket Is Listening....")
connection,address=s.accept() #Accept the Connection
print("Connected To ",address)
msgsend=jpysocket.jpyencode("Thank You For Connecting.") #Encript The Msg
connection.send(msgsend) #Send Msg
msgrecv=connection.recv(1024) #Recieve msg
msgrecv=jpysocket.jpydecode(msgrecv) #Decript msg
print("From Client: ",msgrecv)
s.close() #Close connection
print("Connection Closed.")
Java Client :
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
try{
Socket soc=new Socket("localhost",12345);
DataOutputStream dout=new DataOutputStream(soc.getOutputStream());
DataInputStream in = new DataInputStream(soc.getInputStream());
String msg=(String)in.readUTF();
System.out.println("Server: "+msg);
dout.writeUTF("Ok Boss");
dout.flush();
dout.close();
soc.close();
}
catch(Exception e)
{
e.printStackTrace();
}}}
Python Client :
import jpysocket
import socket
host='localhost' #Host Name
port=12345 #Port Number
s=socket.socket() #Create Socket
s.connect((host,port)) #Connect to socket
print("Socket Is Connected....")
msgrecv=s.recv(1024) #Recieve msg
msgrecv=jpysocket.jpydecode(msgrecv) #Decript msg
print("From Server: ",msgrecv)
msgsend=jpysocket.jpyencode("Ok Boss.") #Encript The Msg
s.send(msgsend) #Send Msg
s.close() #Close connection
print("Connection Closed.")
Java Server :
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
try{
ServerSocket serverSocket = new ServerSocket(12345);
Socket soc = serverSocket.accept();
System.out.println("Receive new connection: " + soc.getInetAddress());
DataOutputStream dout=new DataOutputStream(soc.getOutputStream());
DataInputStream in = new DataInputStream(soc.getInputStream());
dout.writeUTF("Thank You For Connecting.");
String msg=(String)in.readUTF();
System.out.println("Client: "+msg);
dout.flush();
dout.close();
soc.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
If you only want to send a single command on the socket connection, then close the OutputStream after writing the command (using Socket.shutdownOutput()). The socket is reading until EOF and you will not receive EOF until you close the socket. hence, your code never proceeds.
Source - java socket InputStream hangs/blocks on both client and server
Hope it helps!
I have a question, I'm currently working on a little project of mine and stumbled upon a dead end. I have a Java Server :
import java.io.*;
import java.net.*;
class TCPServer
{
public static void main(String argv[]) throws Exception
{
ServerSocket welcomeSocket = new ServerSocket(3443);
Socket clientSocket =null;
ClientHandler ch;
while(true)
{
try{
clientSocket = welcomeSocket.accept();
System.out.println("Client connected on port :"+clientSocket.getPort());
ch = new ClientHandler (clientSocket);
Thread t = new Thread(ch);
t.start();
}catch (Exception e){
System.out.println("SERVER CRASH");
}
}
}
}
Then the client connects through the port 3443, a new thread is created with ClientHandler. Now is the problem, in the client side the socket used to connect is still on port 3443, but on the server side the thread is on an arbitrary port, let's say 5433, so the server can communicate with the thread but not the client, because it has no knowledge of what port the thread is using... I'm a bit confused with all this, does the client class is only needed to make the initial connection, then all the communication is done through the ClientHandler class, if so should i also instantiate an object of ClientHandler in the client class?
Here's my client class :
import java.io.*;
import java.net.*;
class TCPClient
{
static Socket clientSocket = null;
public static void main(String argv[]) throws Exception
{
BufferedReader k = new BufferedReader(new InputStreamReader(System.in));
BufferedReader ine = null;
DataOutputStream oute = null;
try{
clientSocket = new Socket("localhost", 3443);
oute = new DataOutputStream(clientSocket.getOutputStream());
ine = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.out.println("Unknown host");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
System.exit(1);
}
try{
//send
oute.writeBytes(k.readLine());
//recieve
String line = ine.readLine();
System.out.println("Text received: " + line);
} catch (IOException e){
System.out.println("Read failed");
System.exit(1);
}
}
}
The problem is the socket created in client is still connected to Port 3443, and the server is listening to this port, so I won't recieve anything from the server (infinite loop). The clientHandler is on another port. Am i doing it wrong?
You’re calling accept() twice. Call it only once and store the resulting Socket in a variable that you can then hand in to new ClientHandler().
Oh, also, the Socket knows both sides of the communication so it won’t be confused by whatever port the client uses.