trying to connect via TCP to a server using java sockets, the connection gets refused. I'm supposed to send a key to authenticate. code:
Socket clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress("server.address.whatever", 123456));
System.out.println("Connected");
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String key = "key";
outToServer.writeBytes(key + "\r\n");
String response = inFromServer.readLine();
System.out.println("FROM SERVER: " + response);
clientSocket.close();
It never makes it to the point where it tries to print out "Connected", it throws
java.net.ConnectException: Connection refused
So i never send the key. What am i missing here? How can i send an initial message during connecting? Am i even supposed to do that?
It sounds like there is no server process listening on that socket. Check whether you can make a connection with a tool like nmap (or just telnet).
Related
I'm doing a financial messaging integration as follows:
A server has an interface listening for requests from a client socket on a specific IP and port
Server sends a response for every request, back to the client socket
Also, server sends requests to the same client socket
The following is working perfectly:
The client socket (Socket object of Java IO) successfully sends requests to the server interface
The client socket successfully receives response for every request
try {
Socket clientSocket = new Socket("example.com", 8888);
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
output.write(data);
output.flush();
BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Read responses or new request from input
} catch (IOException e) {
e.printStackTrace();
}
The client socket is supposed to receive any request from the server - the same way it's receiving responses from the same sever. However, when a server initiates a request to the client socket, the request is never received. However, we can trace the traffic from the tcpdump on the client environment.
How can I make the client socket listen to requests from the server, and not just responses?
Update
It might help to clarify something on this integration:
a. The 'server' in this case is a third party system, with it's integration rules
b. My client socket posts message to the server (above)
c. My implementation listens to responses and requests from the third party system server, either by creating my own server socket (ruled out), or using the very client socket I'm sending with (the solution I was seeking)
This is a very common mistake, you are writing a message without writing "\n" (end line identifier) at the end so no messages will be read. To fix this use PrintWriter with println.
That will send a line to the other socket.
Here is an example of a thread-per-client model of a server
//create a new server socket with the port as a parameter, this will bind it to the specified port: 6000
ServerSocket server = new ServerSocket(6000);
System.out.println("Binded");
//create a while loop accepting sockets
while(true)
{
//accept a socket
Socket client = server.accept();
System.out.println("Client has connected");
//create a new thread for this socket
new Thread(() ->
{
try
{
/*
create a print writer so you can write a line, not only a message like BufferedWriter does,
if for some reason you still want to use BufferedWriter use
writer.write(message + "\n");
*/
PrintWriter writer = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
//Create a new reader
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Waiting for requests...");
//create a while loop reading requests (lines)
String request;
while((request = reader.readLine()) != null)
{
System.out.println("Received message: " + request);
//here find the correct response and return it, I just sent a message, replace it with the correct response
writer.println("Hello there! How are you today?");
//flush, flushing will write the data to the client
writer.flush();
}
} catch(IOException e)
{
//print an exception if it occurred, if an exception occurrs its most likely just a disconnection exception
e.printStackTrace();
}
}).start();
}
and here is an example of a client
//connect to the server at "localhost" on port 6000
Socket client = new Socket("localhost", 6000);
System.out.println("Connected");
/*
create a print writer so you can write a line, not only a message like BufferedWriter does,
if for some reason you still want to use BufferedWriter use
writer.write(message + "\n");
*/
PrintWriter writer = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
//Create a new reader
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
//write a request
writer.println("Hi there!");
//flush, flushing will write the data to the server
writer.flush();
System.out.println("Written");
System.out.println("Waiting for responses...");
//create a while loop reading responses (lines)
//you may want to do this while loop in another thread
String response;
while((response = reader.readLine()) != null)
{
System.out.println("Received response: " + response);
}
Also if this is involved with financial information I recommend using TLS (SSL).
You don't have to worry Java already has it implemented and has made it easy to use, here is an example of a server
//create a new SSL server socket with the port as a parameter, this will bind it to the specified port: 6000
//you create it by getting the default SSLServerSocketFactory which will create a new SSLServerSocket
//you need to cast it since it actually returns ServerSocket but SSLServerSocket extends ServerSocket and this returns SSLServerSocket so it is safe
SSLServerSocket server = (SSLServerSocket) SSLServerSocketFactory.getDefault().createServerSocket(6000);
System.out.println("Binded");
//set the enabled ciphersuites, until you buy a certificate set only to ciphersuites with "anon" more info on ciphersuites on https://en.wikipedia.org/wiki/Cipher_suite
server.setEnabledCipherSuites(new String[]{"TLS_ECDH_anon_WITH_AES_256_CBC_SHA"});
//create a while loop accepting sockets
while(true)
{
//accept a socket a SSLSocket
SSLSocket client = (SSLSocket) server.accept();
System.out.println("Client has connected");
//create a new thread for this socket
new Thread(() ->
{
try
{
//begin a handshake more info about handshakes in https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10660_.htm
client.startHandshake();
/*
create a print writer so you can write a line, not only a message like BufferedWriter does,
if for some reason you still want to use BufferedWriter use
writer.write(message + "\n");
*/
PrintWriter writer = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
//Create a new reader
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
System.out.println("Waiting for requests...");
//create a while loop reading requests (lines)
String request;
while((request = reader.readLine()) != null)
{
System.out.println("Received message: " + request);
//here find the correct response and return it, I just sent a message, replace it with the correct response
writer.println("Hello there! How are you today?");
//flush, flushing will write the data to the client
writer.flush();
}
} catch(IOException e)
{
//print an exception if it occurred, if an exception occurrs its most likely just a disconnection exception
e.printStackTrace();
}
}).start();
}
And here is an example of a client
//connect to the server at "localhost" on port 6000
//you create a SSLSocket by getting the default SSLSocketFactory which will create a new SSLSocket
//you need to cast it since it actually returns Socket but SSLSocket extends Socket and this returns SSLSocket so it is safe
SSLSocket client = (SSLSocket) SSLSocketFactory.getDefault().createSocket("localhost", 6000);
System.out.println("Connected");
//set the enabled ciphersuites to everything supported so the server can decide the ciphersuite, you can modify this to specified ciphersuites
client.setEnabledCipherSuites(client.getSupportedCipherSuites());
//begin a handshake more info about handshakes in https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10660_.htm
client.startHandshake();
/*
create a print writer so you can write a line, not only a message like BufferedWriter does,
if for some reason you still want to use BufferedWriter use
writer.write(message + "\n");
*/
PrintWriter writer = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
//Create a new reader
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
//write a request
writer.println("Hi there!");
//flush, flushing will write the data to the server
writer.flush();
System.out.println("Written");
System.out.println("Waiting for responses...");
//create a while loop reading responses (lines)
//you may want to do this while loop in another thread
String response;
while((response = reader.readLine()) != null)
{
System.out.println("Received response: " + response);
}
I am creating and testing a simple TCP server on an Android emulator.
I use a simple Java client program to try to connect to the server running on the emulator. I attempt to send a simple string like "hello world".
I think the connection between the client and server is successfully initialized; however, data is not routed to the Android device.
The server thread blocks at line clientSentence = inFromClient.readLine(); and the client thread blocks at String serverResponse = inFromServer.readLine();.
I have port forwarded local host port 6100 to AVD virtual port 7100 as per Google docs with ADB
adb -s emulator-5554 forward tcp:6100 tcp:7100
Here is Java class TCPTestClient
public class TCPTestClient
{
public static void main(String argv[]) throws Exception
{
String sentenceToServer = "hello server";
System.out.println("initializing socket");
Socket clientSocket = new Socket("127.0.0.1", 6100);
System.out.println("socket initialized");
System.out.println("getting output stream to server");
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
System.out.println("found output stream to server");
System.out.println("getting input stream from server");
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
System.out.println("found input stream from server");
System.out.println("writing sentence to server");
outToServer.writeBytes(sentenceToServer );
System.out.println("sentence written");
System.out.println("waiting for sentence response from server");
String serverResponse = inFromServer.readLine();
System.out.println("serverResponse = "+serverResponse);
System.out.println("socket closed");
clientSocket.close();
}
}
Here is Android app method initTcpTestServer()
private void initTcpTestServer()
{
Log.d("TAG", "initTcpTestServer()");
try
{
String clientSentence;
ServerSocket welcomeSocket = new ServerSocket(7100);
while ( true )
{
Log.d("TAG", "looking for socket");
Socket connectionSocket = welcomeSocket.accept();
Log.d("TAG", "socket accepted");
Log.d("TAG", "getting input stream");
BufferedReader inFromClient = new BufferedReader(
new InputStreamReader(connectionSocket.getInputStream()));
Log.d("TAG", "input stream found");
Log.d("TAG", "getting output stream");
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
Log.d("TAG", "output stream found");
Log.d("TAG", "reading input stream");
clientSentence = inFromClient.readLine();
Log.d("TAG", "input stream read");
Log.d("TAG", "input = " + clientSentence);
Log.d("TAG", "writing output back to client");
outToClient.writeBytes(clientSentence);
Log.d("TAG", "output written back to client");
}
}
catch ( IOException e )
{
e.printStackTrace();
}
}
If I initialize the TCP server first I get output
initTcpTestServer()
looking for socket
After initializing the TCP server and then initializing the TCP client I get from the server
getting input stream
input stream found
getting output stream
output stream found
reading input stream
and from the client
initializing socket
socket initialized
getting output stream to server
found output stream to server
getting input stream from server
found input stream from server
writing sentence to server
sentence written
waiting for sentence response from server
so it appears that the socket is established, but the server blocks at line
clientSentence = inFromClient.readLine();
and the client blocks at
String serverResponse = inFromServer.readLine();
becuase the client has written the data, but the server has never received it, and the client is hanging waiting for the server's reponse.
Thank you Scary Wombat. Adding a "\n" at the end of the String resulted in a successful TCP message to the server. A TCP server can indeed be set up on an Android emulator by configuring port forwarding on the AVD virtual router with ADB. However, I have only testing this on local host.
I have a Java TCP server, and an android TCP client. I'm trying to send data from client to server. Sending the data seems to be working fine, but the data that is sent, seems corrupted.
Socket connectionSocket = socket.accept();
BufferedReader inFromClient = new BufferedReader(new InputStreamReader( connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
clientSentence = inFromClient.readLine();
System.out.println(clientSentence);
System.out.println(clientSentence.split(":")[0]);
if(clientSentence.split(":")[0].equals("packet"))
{
When the server receives the data, the prints show something like this in the console:
packet:user:pass
packet
Which is as expected. But still my if isn't returning true. As if the "packet" string got from socket, is different from the one I type with keyboard in my source. I can't even copy the text from console. When I copy with mouse and paste it somewhere, it only copies the first character.
I use the same structures on client side and send the packet with [DataOutputStream].writeChars(message)
I don't know if it's a different coding of characters that cause this, or something else. Also it's worth noting that when i capture the text with wireshark, the string is something like ".p.a.c.k.e.t"
Thanks.
EDIT: As asked, client side code is something like this:
Socket clientSocket = new socket("127.0.0.1", 1234);
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream());
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
String message = "packet:" + username + ":" + password + "\n";
outToServer.writeChars(message);
It's on an android device.
This question already has an answer here:
java.net.ConnectException: Connection refused TCP
(1 answer)
Closed 6 years ago.
I have to establish a TCP connection to a server, which requires that I send the credential to logon in the format:
<STX>username=fred&password=123456<ETX>
Let's say host: qstage.thetcphost.com and port:8999
I am new to socket programming and using the same to implement this. I have used java.net.Socket at the client side but I dont know how do I send the above string for authentication to the TCP Server in Java.
I am able to telnet the server now.
But how do I pass the credential string in the < STX >...< ETX > format after (or during):
Socket socket = new Socket("mshxml.morningstar.com", 8999);
I mean what is the piece of code that I have to write to authenticate myself to the TCP server?
I have searched this site for this info but could not find any.
Help would be greatly appreciated.
Establish the socket connection is the first step before you can send any creds information.
If this step is failing, consider the specs from your target server. Is the correct port provided? Any consideration on protocol?
Usually, the authentication will be happen after you have already established successfully the connection.
Editted: Add source code for writing to socket from a socket client.
Now, in this context, you're a socket client, try to send creds to server.
public class GreetingClient
{
public static void main(String [] args)
{
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try
{
System.out.println("Connecting to " + serverName +
" on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to "
+ client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from "
+ client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in =
new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
}catch(IOException e)
{
e.printStackTrace();
}
}
}
Sample found here: http://www.tutorialspoint.com/java/java_networking.htm
i'm trying to find out how to create a TCP server with SSL in java. But i don't get what i really need. Do i have to import key-files into java, and i so, how to do this? Or do i just need to change the type of the socket from Socket to SSLSocket? I've read some articles but couldn't find anything helpful because all of them just take http for communicating. I would need it for my own protocol. In my case it would be to have a program like this:
int port = 4444;
ServerSocket serverSocket = new ServerSocket(port);
System.err.println("Started server on port " + port);
// repeatedly wait for connections, and process
while (true) {
// a "blocking" call which waits until a connection is requested
Socket clientSocket = serverSocket.accept();
System.err.println("Accepted connection from client");
// open up IO streams
In in = new In (clientSocket);
Out out = new Out(clientSocket);
// waits for data and reads it in until connection dies
// readLine() blocks until the server receives a new line from client
String s;
while ((s = in.readLine()) != null) {
out.println(s);
}
// close IO streams, then socket
System.err.println("Closing connection with client");
out.close();
in.close();
clientSocket.close();
}
to use a SSL connection. So how to do this?
Thanks,
Thomas
I found this with a quick Google search.
Here.