I have a TCP Server written in java. I am trying to connect to it via a TCP client socket written in dartlang but the client written in dartlang times out almost immediately after the initial connection (my five second timeout set in the java code). I was able to send a message to the dart client in a test immediately after it connected but it soon timed out. However the data in the dartlang '{"packet_id":1}' never gets received by the server.
I tried writing a test server in dartlang and it was able to connect and send/receive messages without any issues.
Dart Client:
import 'dart:io';
import 'dart:async';
main(List<String> arguments) {
Future<Socket> future = Socket.connect('localhost', 12345);
future.then((client) {
print('connected to server!');
client.handleError((data){
print(data);
});
client.listen(
(data) {
print(new String.fromCharCodes(data));
},
onDone:(){
print("Done");},
onError: (error) {
print(error);
}
);
String requestHalls = '{"packet_id":1}';
client.write(requestHalls);
}).catchError(() {print('Error connecting');});
print('Hello world: ${dart_test.calculate()}!');
}
My Java client connects to the Java Server socket just fine.
EDIT: adding java code
creating the serversocket.
#Override
public void run() {
// Create Server Socket for clients to connect to
try {
// load data from config manager
ConfigManager config = HDAServer.getConfigManager();
int port = config.getServerPort();
String ip = config.getServerURL();
Inet4Address inet4 = (Inet4Address) Inet4Address.getByName(ip); // this allows for binding to domain name or ipv4 address
HDAServer.getLogger().info(String.format("Opening Server Socket at address(%s)= %s:%s", ip, inet4.getHostAddress(), port));
// attempt to bind
serverSocket = new ServerSocket(config.getServerPort(), 50, inet4);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// wait for incoming client connections
waitForConnections();
}
/**
* Method that waits for incoming connections, adds the connection to a new pool, and creates a
* new thread for the connection to run on.
*/
private void waitForConnections() {
// loop through waiting for incoming connections until server shuts down
while (!shutdown) {
Socket socket = null;
try {
// blocks thread waiting for a connection
socket = serverSocket.accept();
} catch (IOException e) {
if (e.getMessage().equals("socket closed")) {
HDAServer.getLogger().info("Shutting Down Server Socket");
continue;// skip to while check
} else {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// create our connection class, start it in a new thread, and add it to our connection list
HDAServerConnection newConn = new HDAServerConnection(socket);
new Thread(newConn).start();
connections.add(newConn);
HDAServer.getLogger().info(String.format("Client connected from: %1s", newConn.getRemoteIP()));
// reap dead connections
this.reapDeadConnections();
}
}
Servers "Client" HDAConnection class:
protected Socket socket;
protected DataInputStream inputStream;
protected DataOutputStream outputStream;
private boolean shutdown = false;
public HDAConnection(Socket socket) {
this.socket = socket;
// configure socket
try {
socket.setKeepAlive(true);
socket.setSoTimeout(5000);
socket.setTcpNoDelay(true);
} catch (SocketException ex) {
AbstractHDALogger.get().severe("Error configuring Socket Connection.", ex);
}
// create input/output stream for handling data
try {
inputStream = new DataInputStream(socket.getInputStream());
outputStream = new DataOutputStream(socket.getOutputStream());
} catch (IOException ex) {
AbstractHDALogger.get().severe("Error creating input/output streams.", ex);
}
}
code that is listening for a message over the stream.
String response = null;
try {
response = new BufferedReader(new InputStreamReader(inputStream)).readLine();
} catch(SocketTimeoutException ste) {
shutdown();
AbstractHDALogger.get().severe(String.format("Socket Timed out(%s), closing Connection", this.getRemoteIP()), ste);
// TODO: handle exception
} catch (IOException e) {
// TODO Make this better?
// IO Exception probably means client disconnected, so we should terminate.
if (e.getMessage().equals("Connection reset")) {
shutdown();
AbstractHDALogger.get().info(String.format("Client Connection Disconnected(%s). Closing connection.", this.getRemoteIP()));
} else {
shutdown();
AbstractHDALogger.get().severe(String.format("Connection Error(%s), closing Connection", this.getRemoteIP()), e);
}
return null;
}
The socket is timing out on the Java Server because the dartlang client is never writing a newline at the end of its message and the Java Server is using the readline method to read. This function will only return when it reads a new line character. After reading the initial message from the dartlang client the Java server waits five seconds for more data to be sent but will time out as nothing more is ever sent.
The dartlang client should use the writeln function or appent a newline character to the end of its messages for the Java server BufferedReader to return.
Related
I have java client server application. Server is running or may not be connected. but we need to connect with ip and port.
Socket s=new Socket(ip,port);
if it is connected, socket will be created, else it throws IOException. then i will set a status of that connection as not connected in an object.
if connected, i will send data as commands. It will respond to that command with data. We send commands with output stream and read responce with input-stream of the socket.
I need to automatically reconnect to the server when server is available (wired or wifi connection).
How to Use Multi threading here
ex:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
public class ConnectionThread implements Runnable {
static class ConnectionStatus {
boolean connected = false;
public boolean isConnected() {
return connected;
}
public void setConnected(boolean connected) {
this.connected = connected;
}
}
ConnectionStatus status;
Socket socket;
String ip;
int port;
public ConnectionThread(ConnectionStatus status, String ip, int port) {
this.status = status;
this.ip = ip;
this.port = port;
}
public void connectAgain() throws IOException {
while (!status.isConnected()) {
socket = new Socket(ip, port);
status.setConnected(true);
}
}
public void run() {
try {
connectAgain();
} catch (IOException e) {
try {
Thread.sleep(1000);
connectAgain();
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public static void main(String[] args) {
ConnectionStatus status = new ConnectionStatus();
status.setConnected(false);
ConnectionThread cthread = new ConnectionThread(status, "192.166.102.201", 1986);
Thread x = new Thread(cthread);
x.start();
System.out.println("Connected ..." + status.isConnected());
}
}
I need to send commands (data) only when connected to receive response.
I need to set the connected status to false when not connected
and to true when connected.
Based on connected status i will read from socket or write to socket steams.
I need to know when the connection is failed
and when the connection is available.
I think better to use propertychangelistener when connected property is changed.
is it right?
This loop really has no point.
while (!status.isConnected()) {
socket = new Socket(ip, port);
status.setConnected(true);
}
Whether it succeeds or fails it can never execute the loop more than once. It has exactly the same effect as just this:
socket = new Socket(ip, port);
status.setConnected(true);
The run will call this twice with a 1 second delay unless it doesn't throw an exception and succeeds. If you want it to keep trying until you connect, you need to catch the exception within the loop. eg
Socket s = new Socket();
SocketAddress sa = new InetSocketAddress("192.166.102.201", 1986);
while (!s.isConnected()) {
try {
s.connect(sa); // try the connection
} catch (IOException ex) {
// ignore we may have to try lots of times
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
// not sure how to handle this, maybe we should just give up.
}
}
}
Update: I had both the sleep and the connect in the same try block which meant it would never sleep but just keep the thread always busy. Moved the sleep to separate block.
I need to develop a Java server which listens on a port on my pc.
Multiple clients (on the same PC) will access that port and the server should invoke a common method (for all clients, like file copying) which I have written in another class.
My input would be a file path through command line from each client on to that port.
It should invoke a thread each time a client accesses the port.
You can use the server socket class from the java.net package for creating a socket which will listen to incoming client connections on that port. On accepting new connections, start a new thread specific to that client which will handle that client while the server can continue to listen for new connections . Put the common method which you want the server to invoke in the run() method of the new thread.
public class server {
public static void main (String[] args)
{
ServerSocket sock = new ServerSocket (6666); // Server Socket which will listen for connections
try{
while(true)
{
new clientThread(sock.accept()).start(); // start a new thread for that client whenever a new request comes in
}
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
finally {
sock.close();
}
}
// Client Thread for handling client requests
private static class clientThread extends Thread {
Socket socket ;
BufferedReader in ;
PrintWriter out;
clientThread(Socket socket) throws IOException
{
this.socket = socket ;
}
public void run()
{
try
{
// create streams to read and write data from the socket
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
// put your server logic code here like reading from and writing to the socket
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try {
socket.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
}
You can refer to the documentation for further information about the java socket API
All About Sockets - Oracle
I am new to JAVA/Android TCP connection. I try to implement a TCP Server like the following code.
private class TCPServerThread implements Runnable
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while (true) {
try {
socket = serverSocket.accept();
ClientAddress = socket.getInetAddress();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
I can send message to the client when I get the socket by socket = serverSocket.accept();
-----------------------------Question-----------------------------
Do I need to set different port for client ?
But How to get the multiple socket from the multiple client ?
Do I need to set different port for client
No.
But How to get the multiple socket from the multiple client?
Your code already does that.
I have a program running on a server (Server A) which listens on one port for an external connection (from an external server, B), then listens on another port for an internal connection on the same server (Server A). It then passes data from the internal to external connection and back again.
I want to know if there is a way I can detect that the client external was disconnected. I just need one external connection at a time, but I would like to be able to accept a new one if the external client reboots or something like that.
This socket level stuff is all fairly new to me, so if there is a better way of going about this, I'm all ears. The one stipulation is that the client running on Server B must be the one to initiate the connection and the connection must live for as long as possible.
public void handleConnection() {
System.out.println("Waiting for client message...");
try {
SSLSocket extSocket = (SSLSocket) this.externalServerSocket.accept();
ObjectInputStream externalOis = new ObjectInputStream(extSocket.getInputStream());
ObjectOutputStream externalOos = new ObjectOutputStream(extSocket.getOutputStream());
System.out.println("Client connection establisthed");
// Loop here to accept all internal connections
while (true) {
SSLSocket internalSocket = (SSLSocket) this.internalServerSocket.accept();
new ConnectionHandler(externalOis, externalOos, internalSocket);
}
} catch (IOException e) {
System.err.println(e.getMessage());
return;
}
}
class ConnectionHandler implements Runnable {
private SSLSocket internalSocket;
private ObjectOutputStream internalOos;
private ObjectInputStream internalOis;
private ObjectInputStream externalOis;
private ObjectOutputStream externalOos;
public ConnectionHandler(ObjectInputStream externalOis,
ObjectOutputStream externalOos, SSLSocket internalSocket) {
this.internalSocket = internalSocket;
try {
this.internalOis = new ObjectInputStream(this.internalSocket.getInputStream());
this.internalOos = new ObjectOutputStream(this.internalSocket.getOutputStream());
this.externalOis = externalOis;
this.externalOos = externalOos;
} catch (IOException e) {
System.err.println(e.getMessage());
}
new Thread(this).start();
}
#Override
public void run() {
try
{
// process data
Object o = internalOis.readObject();
externalOos.writeObject(o);
Object o2 = externalOis.readObject();
internalOos.writeObject(02);
internalOos.close();
internalOis.close();
this.internalSocket.close();
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (ClassNotFoundException e) {
System.err.println(e.getMessage());
}
}
}
If the client disconnects, readObject() will throw EOFException, and write() will throw an IOException: connection reset. That's all you need.
I am trying to write a client-server system using Sockets in java, however I cannot seem to read data sent from the server to the client.
Here is the code for the client:
public class ClientSocket
{
Socket clientSocket = null;
PrintWriter out = null;
BufferedReader in = null;
// establish a connection to All Care's server application through socket 4444 (adjust localhost to reflect the IP address that the server
// is being run from)
public ClientSocket()
{
try
{
clientSocket = new Socket("localhost", 4445);
out = new PrintWriter(clientSocket.getOutputStream());
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
}
catch (IOException e)
{
System.out.println("Could not connect to All Care Server Application");
}
}
public void closeClientSocket()
{
try
{
clientSocket.close();
}
catch (IOException e)
{
System.out.println("Could not close connection to All Care Server Application");
}
}
public String getMessageFromServer()
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from server");
}
return "No Data";
}
public void sendMessageToServer(String message)
{
out.write(message);
}
}
And here is the Server code:
public class ArFileServer {
public static void main(String[] args)
{
ServerSocket serverSocket = null;
boolean listening = true;
try
{
serverSocket = new ServerSocket(4445);
// infinite loop to continually listen for connection requests made by clients
while (listening)
{
new ClientConnection(serverSocket.accept()).start();
if (serverSocket != null)
{
System.out.println("Connection to client established");
}
}
serverSocket.close();
}
catch (IOException e)
{
System.out.println("Error could not create socket connection to port");
}
}
}
public class ClientConnection extends Thread
{
private Socket socket = null;
public ClientConnection(Socket socket)
{
super("ClientConnection");
this.socket = socket;
}
// the thread that runs after a connection to the server has been accepted
#Override
public void run()
{
try
{
PrintWriter out = new PrintWriter(socket.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
sendMessagetoClient(out, "CONNECTION SUCCESS");
// check login credentials sent from client to the server
// if valid send back their encrypted password, otherwise output a login error message
// wait for user input and then do various processes based on their requests
in.close();
out.close();
socket.close();
}
catch (IOException e)
{
System.out.println("Client socket connection error");
}
}
// sends a message to the client
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
}
// listens for a message from the client
String getMessageFromClient(BufferedReader in)
{
try
{
String input = in.readLine();
return input;
}
catch (IOException e)
{
System.out.println("Could not read message from client");
}
return "No Data";
}
And here is the line of code im using to see if the data is being sent.
System.out.println(clientSocket.getMessageFromServer());
In your sendMessageToClient() method, you need to flush:
void sendMessagetoClient(PrintWriter out, String message)
{
out.write(message);
out.flush();
}
Or, when you create the PrintWriter, use the constructor with autoflush:
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
And when you write, instead of out.write(message) use printf() or println().
There are several problems here.
You are reading lines but you aren't writing lines.
You aren't checking the result of readLine() for null, which means the peer has closed the connection, which means you must do likewise.
You aren't flushing the PrintWriter after you write.
You are closing things in the wrong order. You must close the output writer/stream you have attached to the socket. Doing that flushes it and then closes the input stream/reader and the socket. Doing this in the wrong order loses the flush. Once you've closed the output you don't need the other two closes.
You are using PrintWriter, which swallows exceptions, across a network, where you need to know about exceptions and errors in communication, and you aren't checking for errors either. Use a BufferedWriter.
in the clint code you are not connecting with server socket.
for clint socket connection
socket soc= new socket ("server host ip",port);