I'm tring to implement a java - python client/server socket. The client is in java and the server is write in python
Java Client
import java.io.*;
import java.net.*;
import java.lang.*;
public class client {
public static void main(String[] args) {
try{
Socket socket=new Socket("localhost",2004);
DataOutputStream dout=new DataOutputStream(socket.getOutputStream());
DataInputStream din=new DataInputStream(socket.getInputStream());
dout.writeUTF("Hello");
dout.flush();
System.out.println("send first mess");
String str = din.readUTF();//in.readLine();
System.out.println("Message"+str);
dout.close();
din.close();
socket.close();
}
catch(Exception e){
e.printStackTrace();}
}
}
Python server
import socket
soc = socket.socket()
host = "localhost"
port = 2004
soc.bind((host, port))
soc.listen(5)
while True:
conn, addr = soc.accept()
print ("Got connection from",addr)
msg = conn.recv(1024)
print (msg)
print(len(msg))
if "Hello"in msg:
conn.send("bye".encode('UTF-8'))
else:
print("no message")
The first message from client to server was delivery correctly but the second from server to client no. Using telnet I check that sever send the message but the client goes in deadlock and don't receive message.
I don't understand why.
Thanks
It seems that your indentation is off in the Python server, as the code to send
the message back to the client is unreachable.
Even after fixing the indentation, your server implementation is not correct, as msg is not a String. You need to decode msg as seen below. Also, you need to send the length of the message as a short since you're using DataInputStream#readUTF in your client:
import socket
soc = socket.socket()
host = "localhost"
port = 2004
soc.bind((host, port))
soc.listen(5)
while True:
conn, addr = soc.accept()
print("Got connection from",addr)
length_of_message = int.from_bytes(conn.recv(2), byteorder='big')
msg = conn.recv(length_of_message).decode("UTF-8")
print(msg)
print(length_of_message)
# Note the corrected indentation below
if "Hello"in msg:
message_to_send = "bye".encode("UTF-8")
conn.send(len(message_to_send).to_bytes(2, byteorder='big'))
conn.send(message_to_send)
else:
print("no message")
Related
I'm trying to send an MSEARCH datagram packet to discover my Roku device on my LAN. I have this implemented in Java already, and it works fine, however I'm trying to learn Haskell. While I'm not getting any compilation errors, the code is hanging during a call to recv.
Here's my work in progress, shamelessly mostly plagiarized from the Network.Socket.ByteString documentation page.
import Network.Socket hiding (recv)
import Network.Socket.ByteString (recv, sendAll)
import qualified Data.ByteString.Char8 as C
msearch = "M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\nST: roku:ecp\r\n\r\n"
main :: IO ()
main = withSocketsDo $
do addrinfos <- getAddrInfo Nothing (Just "239.255.255.250") (Just "1900")
let serveraddr = head addrinfos
sock <- socket (addrFamily serveraddr) Datagram defaultProtocol
connect sock (addrAddress serveraddr)
putStrLn "Sending: "
putStrLn msearch
sendAll sock $ C.pack msearch
msg <- recv sock 1024
close sock
putStr "Got response: "
C.putStrLn msg
In Java:
import java.net.*;
public class Msearch {
public static void main(String[] args) {
try {
// MSEARCH query
String MSEARCH = "M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nMan: \"ssdp:discover\"\r\nST: roku:ecp\r\n\r\n";
byte[] sendData = MSEARCH.getBytes();
// Send a datagram packet
System.out.println("Sending:\n" + MSEARCH);
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, InetAddress.getByName("239.255.255.250"), 1900);
DatagramSocket clientSocket = new DatagramSocket();
clientSocket.send(sendPacket);
// Wait for response & close
byte[] receiveData = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
clientSocket.receive(receivePacket);
clientSocket.close();
// Print the response
String response = new String(receivePacket.getData());
System.out.println("Got response:\n" + response);
} catch (Exception e) {
// ...
}
}
}
The Java version works perfectly, yielding:
Sending:
M-SEARCH * HTTP/1.1
Host: 239.255.255.250:1900
Man: "ssdp:discover"
ST: roku:ecp
Got response:
HTTP/1.1 200 OK
Cache-Control: max-age=3600
ST: roku:ecp
USN: uuid:roku:ecp:2N00G7750045
Ext:
Server: Roku UPnP/1.0 MiniUPnPd/1.4
LOCATION: http://192.168.1.169:8060/
The Haskell version hangs on the call to recv. I'm still learning Haskell and I'm not sure what I'm doing differently that may be causing this. I would be grateful for any insights!
I am doing a simple Java Client application which should communicate with Python Server. I can easily send a string to Python Server and print it in console, but when i'm trying to use received string in IFs it never get into IF statement even if it should.
Here is Java Client send msg code
socket = new Socket(dstAddress, dstPort);
dataOutputStream = new DataOutputStream(
socket.getOutputStream());
dataInputStream = new DataInputStream(socket.getInputStream());
if(msgToServer != null){
dataOutputStream.writeUTF("UP");
}
System.out.println(dataInputStream.readLine());
And Python Server code:
import socket
HOST = ''
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)
print 'Socket now listening'
conn, addr = s.accept()
print 'Connected to: ' + addr[0] + ':' + str(addr[1])
data = conn.recv(1024)
if data == "UP":
conn.sendall('Works')
else:
conn.sendall('Does not work')
conn.close()
s.close()
print data
So when i send to Python Server "UP" it should send back to Java Client "Works", but i reveive "Does not work" and in Python Server the output data is: "UP"
Why it isn't go into if statement?
The JavaDoc of DataOutputStream#writeUTF(...) says:
First, two bytes are written to the output stream as if by the
writeShort method giving the number of bytes to follow
In you python code your data value will be prefixed with two bytes for the length of the string to follow.
I am trying to create a p2p connection. This is a just test app that i have check but seems like it does not work over internet.
This is the java code that I am using on my pc to send a datagram to my friend:
'
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import javax.net.ssl.SSLServerSocket;
public class j2{
public static void main(String[] args) throws Exception {
InetAddress IPAddress = InetAddress.getByName("my friend's public IP");
DatagramSocket clientSocket = new DatagramSocket(3456);
System.out.println("Sending data");
String datamsg = "hello ";
byte[] sendData = datamsg.getBytes("UTF-8");
byte [] receiveData = new byte[10];
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 7890);
int i = 500;
//incase if some packets are lost
while(i-->1)
{
clientSocket.send(sendPacket);
}
System.out.println("Data sent");
System.out.println(clientSocket.isClosed());
clientSocket.close();
}
}
'
//My friend uses this app to receive a data gram:
// port 7890 is used to send data gram and create a hole. The same is used to receice data.
'
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import javax.net.ssl.SSLServerSocket;
public class j1{
public static void main(String[] args) throws Exception {
InetAddress IPAddress = InetAddress.getByName("any ip"); //does not matter as it is used to open a hole
DatagramSocket clientSocket = new DatagramSocket(7890);
System.out.println("Sending data");
String datamsg = "hello ";
byte[] sendData = datamsg.getBytes("UTF-8");
byte [] receiveData = new byte[10];
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, IPAddress, 5000);
int i = 500;
while(i-->1)
{
clientSocket.send(sendPacket);
}
System.out.println("Data sent");
System.out.println(clientSocket.isClosed());
DatagramPacket receivePacket = new DatagramPacket(sendData, sendData.length);
clientSocket.receive(receivePacket);
System.out.println("Packet received");
String msg = new String(receivePacket.getData());
clientSocket.close();
}
}'
// I am not using a stun server as i already know my friends public ip address. We both have disabled our firewall as well.
Your approach is not the most reliable way to do NAT hole punching. At best it will "sometimes work".
Here's some suggestions:
Don't hardcode port numbers. Let your UDP socket code pick a random port number (i.e. port=0) and use a STUN server (or equivalent) to ascertain your public IP address and public port mapping for this local socket.
Use a reliable service to exchange the IP/port. Since you are just trying to get a single packet to go through, start with using a phone to verbally exchange this information could suffice.
You don't need to send 500 packets all at once. The firewall code on
the remote NAT might see this as a DOS attack and block everything.
Try sending like 1 a second.
You should be simultaneously listening and sending periodic packets at the same time
when trying to do the connectivity check that your code is doing.
(e.g. two seperate threads or periodic polling).
Don't close the socket until after connectivity is confirmed by both endpoints. As you have it now, your first program closes the socket immediately after it sends the packet burst.
Read my full answer here: https://stackoverflow.com/a/8524609/104458
I've very new to networking and using networks to send messages through programming. Anyways, I have a client and server java command line application (server is running in a VM on the same machine with a bridged network adapter, and host to guest pinging works and vice versa), and it would appear on the server side that each message it receives is coming from a different port. Is this normal behavior? What happens when the machine runs out of ports to use? Does Java's libraries intelligently close the ports after it's done with them?
So basically, is this even a problem? If it is, how do I go about fixing it? Output from the server and then code for the client listed below.
SERVER OUTPUT AFTER SENDING SOME MESSAGES:
Received (/192.168.1.122:59628): shsfh
Received (/192.168.1.122:59629): dfsh
Received (/192.168.1.122:59631): dfh
Received (/192.168.1.122:59632): fdshdf
Received (/192.168.1.122:59633): shf
Received (/192.168.1.122:59637): fgfggsdfhsfdh
Received (/192.168.1.122:59638): fdshf
Received (/192.168.1.122:59639): hs
Received (/192.168.1.122:59640): hfh
CODE FOR THE CLIENT THAT SENT THOSE MESSAGES:
import java.io.*;
import java.util.*;
import java.net.*;
class TCPClient
{
public static void main(String argv[]) throws Exception
{ Scanner scan = new Scanner(System.in);
while (true)
{
String msgcont = scan.nextLine();
System.out.println(tcpSend("192.168.1.153", 6789, 5000, msgcont));
}
}
public static String tcpSend(String ip, int port, int timeout, String content)
{
String ipaddress = ip;
int portnumber = port;
String sentence;
String modifiedSentence;
Socket clientSocket;
try
{
clientSocket = new Socket(ipaddress, portnumber);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(content + '\n');
clientSocket.setSoTimeout(timeout);
modifiedSentence = inFromServer.readLine();
clientSocket.close();
outToServer.close();
inFromServer.close();
}
catch (Exception exc)
{
modifiedSentence = "";
}
return modifiedSentence;
}
}
Yes, everytime you open a socket to other host, the connection can be initiated from any of the remaining port on your machine. The OS chooses the next available port and makes the connection.
There are 65536 open ports available from which first 1-1024 ports are reserved by the system.
My aim is to send a message from python socket to java socket. I did look out on the resource mentioned above. However I am struggling to make the Python client talk to Java server. Mostly because (End of line) in python is different from that in java.
say i write from python client: message 1: abcd message 2: efgh message 3: q (to quit)
At java server: i receive message 1:abcdefghq followed by exception because the python client had closed the socket from its end.
Could anybody please suggest a solution for a consistent talk between java and python.
Reference I used: http://www.prasannatech.net/2008/07/socket-programming-tutorial.html
Update: I forgot to add, I am working on TCP.
My JAVA code goes like this:(server socket)
String fromclient;
ServerSocket Server = new ServerSocket (5000);
System.out.println ("TCPServer Waiting for client on port 5000");
while(true)
{
Socket connected = Server.accept();
System.out.println( " THE CLIENT"+" "+ connected.getInetAddress() +":"+connected.getPort()+" IS CONNECTED ");
BufferedReader inFromClient = new BufferedReader(new InputStreamReader (connected.getInputStream()));
while ( true )
{
fromclient = inFromClient.readLine();
if ( fromclient.equals("q") || fromclient.equals("Q") )
{
connected.close();
break;
}
else
{
System.out.println( "RECIEVED:" + fromclient );
}
}
}
My PYTHON code : (Client Socket)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(("localhost", 5000))
while 1:
data = raw_input ( "SEND( TYPE q or Q to Quit):" )
if (data <> 'Q' and data <> 'q'):
client_socket.send(data)
else:
client_socket.send(data)
client_socket.close()
break;
OUTPUT::
ON PYTHON CONSOLE(Client):
SEND( TYPE q or Q to Quit):abcd ( pressing ENTER)
SEND( TYPE q or Q to Quit):efgh ( pressing ENTER)
SEND( TYPE q or Q to Quit):q ( pressing ENTER)
ON JAVA CONSOLE(Server):
TCPServer Waiting for client on port 5000
THE CLIENT /127.0.0.1:1335 IS CONNECTED
RECIEVED:abcdefghq
Append \n to the end of data:
client_socket.send(data + '\n')
ya..you need to add '\n' at the end of the string in python client.....
here's an example...
PythonTCPCLient.py
`
#!/usr/bin/env python
import socket
HOST = "localhost"
PORT = 8080
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.sendall("Hello\n")
data = sock.recv(1024)
print "1)", data
if ( data == "olleH\n" ):
sock.sendall("Bye\n")
data = sock.recv(1024)
print "2)", data
if (data == "eyB}\n"):
sock.close()
print "Socket closed"
`
Now Here's the java Code:
JavaServer.java
`
import java.io.*;
import java.net.*;
class JavaServer {
public static void main(String args[]) throws Exception {
String fromClient;
String toClient;
ServerSocket server = new ServerSocket(8080);
System.out.println("wait for connection on port 8080");
boolean run = true;
while(run) {
Socket client = server.accept();
System.out.println("got connection on port 8080");
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(),true);
fromClient = in.readLine();
System.out.println("received: " + fromClient);
if(fromClient.equals("Hello")) {
toClient = "olleH";
System.out.println("send olleH");
out.println(toClient);
fromClient = in.readLine();
System.out.println("received: " + fromClient);
if(fromClient.equals("Bye")) {
toClient = "eyB";
System.out.println("send eyB");
out.println(toClient);
client.close();
run = false;
System.out.println("socket closed");
}
}
}
System.exit(0);
}
}
`
Reference:Python TCP Client & Java TCP Server
here is a working code for the same:
Jserver.java
import java.io.*;
import java.net.*;
import java.util.*;
public class Jserver{
public static void main(String args[]) throws IOException{
ServerSocket s=new ServerSocket(5000);
try{
Socket ss=s.accept();
PrintWriter pw = new PrintWriter(ss.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedReader br1 = new BufferedReader(new InputStreamReader(ss.getInputStream()));
//String str[20];
//String msg[20];
System.out.println("Client connected..");
while(true)
{
System.out.println("Enter command:");
pw.println(br.readLine());
//System.out.println(br1.readLine());
}
}
finally{}
}
}
Client.py
import socket # Import socket module
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 5000 # Reserve a port for your service.
s.connect((host, port))
while 1:
print s.recv(5000)
s.send("message processed.."+'\n')
s.close
I know it is late but specifically for your case I would recommend RabbitMQ RPC calls. They have a lot of examples on their web in Python, Java and other languages:
https://www.rabbitmq.com/tutorials/tutorial-six-java.html
for the people who are struggling with,
data = raw_input ( "SEND( TYPE q or Q to Quit):" )
your can also use
.encode() to send the data