Kryonet Client immediately disconnecting from server - java

I am currently in the process of writing an app which has the phone connect to a server.
Both client and server are using the Kryonet framework.
The problem ist the following :
When the server is running and I then start up the client, the client immediately disconnects from the server but the Programm itself keeps running so it is only possible that the client Thread died for whatever reason.
I am using kryonet-2.21 on both server and client.
I tried my code on Android aswell as on pc.
I also tried to troubleshoot everything I could and tried everything I found searching for my problem.
The Client code :
public class LogicHandler extends Thread {
private Client client;
public LogicHandler() {
}
public Client getClient() {
return client;
}
public void run() {
client = new Client(33554432, 33554432);
new Thread(client).start();
try {
getClient().connect(5000, "localhost", 54555, 54777);
} catch (IOException e) {
e.printStackTrace();
}
Packets.register(getClient());
getClient().addListener(new Listener() {
public void received(Connection connection, Object object) {
System.out.println("received " + object);
if (object instanceof ConnectionResponse) {
}
if (object instanceof ScheduleResponse) {
}
}
public void disconnected(Connection connection) {
}
});
getClient().sendTCP(new ConnectionRequest());
}
public static void main(String[] args) {
new LogicHandler().start();
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("wait");
}
}
}
The Server code :
public class ServerLogicHandler {
private Server server;
private List<Client> clients;
private List<Connection> connections;
public ServerLogicHandler() {
System.out.println("Server is starting!");
server = new Server(33554432, 33554432);
server.start();
try {
server.bind(54555, 54777);
} catch (Exception e) {
server.stop();
System.out.println("Port belegt. Server wird gestoppt!");
System.exit(0);
}
Packets.register(server);
clients = new ArrayList<Client>();
connections = new ArrayList<Connection>();
server.addListener(new Listener() {
public void received(Connection connection, Object object) {
System.out.println("got packet");
if (object instanceof ConnectionRequest) {
System.out.println("size " + connection.sendTCP(new ScheduleResponse()));
}
}
public void disconnected(Connection connection) {
System.out.println("Disco " + connection.getID());
}
public void connected(Connection connection) {
System.out.println(connection.getRemoteAddressTCP().getPort() + " "
+ connection.getRemoteAddressTCP().getAddress());
}
});
System.out.println("Server started!");
}
public Server getServer() {
return server;
}
public static void main(String... args) {
new ServerLogicHandler();
}
}
The client doesn't output anything apart from the 'wait' every second. This means that either the server didn't send any packet or the client closed already. My guess is that the latter happened because the server outputs the following :
Server is starting!
Server started!
54408 /127.0.0.1
Disco 1
When I start a new client the last 2 lines would just repeat e.g. '54890 /127.0.0.1
Disco 2
'
From this I guess that the client closes for whatever reason before even sending any packets. None of my Google searches brang up any success.

Related

Need help understanding TCP Channels

I have a machine running that sends out status information over TCP to an IP address and port you set on the machine. If I use the command line for the machine on that IP address and run "nc -l " I get the status data from the machine. I am trying to build a Java Spring application to ingest this but all the Java TCP tutorials talk about setting channel names and subscribing to channels? Are channels something that are built on top of TCP and my machine just isn't using channels or is there some default channel listened on when you run the command line "nc -l " command? Please Help I'm very confused
EDIT 1: Adding first attempt code that I can't get to integrate with the Spring application nor can I get the data to store in Spring JPA
public class EchoMultiServer {
private ServerSocket serverSocket;
public void start(int port) {
try {
serverSocket = new ServerSocket(port);
while (true)
new EchoClientHandler(serverSocket.accept()).start();
} catch (IOException e) {
e.printStackTrace();
} finally {
stop();
}
}
public void stop() {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static class EchoClientHandler extends Thread {
private Socket clientSocket;
private PrintWriter out;
private BufferedReader in;
#Autowired
PowerStationService powerStationService;
//this service connects to the repository to store the data
public EchoClientHandler(Socket socket) {
this.clientSocket = socket;
}
public JSONObject mapJsonInput(String incomingText){
try{
JSONObject json = new JSONObject(incomingText);
return json;
} catch (JSONException e){
System.out.println("JSONException " + e);
return null;
}
}
public JSONObject run() {
try {
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
StringBuilder textBuilder = new StringBuilder();
int c = 0;
int leftCaratCount=0;
int rightCaratCount=0;
while ((c = in.read()) != -1) {
char character = (char) c;
textBuilder.append(character);
if (character == '{') {
leftCaratCount++;
} else if (character == '}') {
rightCaratCount++;
if (rightCaratCount == leftCaratCount) {
System.out.println(textBuilder);
JSONObject registrationJson = mapJsonInput(textBuilder.toString());
System.out.println("we got em");
powerStationService.save(new PowerStation(registrationJson.get("D").toString(), registrationJson.get("G").toString(), Integer.parseInt(registrationJson.get("Y").toString()), Integer.parseInt(registrationJson.get("S").toString()), registrationJson.get("C").toString(), registrationJson.get("Z").toString(), registrationJson.get("V").toString()));
out.println("000250{\"A\":\"45514\",\"C\":\""+registrationJson.get("Y")+"\",\"E\":\"30,5\",\"G\":\""+registrationJson.get("G")+"\",\"H\":\"0\",\"K\":\"1\",\"M\":\"123456\",\"N\":\"" + System.currentTimeMillis() + "\",\"O\":\"13371\",\"P\":\"" + clientSocket.getLocalAddress().getHostAddress() + "\",\"S\":\"60000\",\"U\":\"\",\"V\":\"\",\"W\":\"https://admin.chargenow.top/cdb-socket-api/v1/socketserver/common\",\"X\":\"0\",\"Y\":\"FJC\",\"Z\":\"\"}");
in.close();
out.close();
clientSocket.close();
}
}
}
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
public static void main(String[] args) {
EchoMultiServer server = new EchoMultiServer();
server.start(13370);
}
}
EDIT 2: Additionally I attempted to use the example from the Spring Examples Github to see if it could receive messages on the port I tried. I'm able to use NetCat to see the ServerOut messages but the application isn't receiving responses back
#SpringBootApplication
#EnableConfigurationProperties(SampleProperties.class)
public class TcpAsyncBiDirectionalApplication {
public static void main(String[] args) {
SpringApplication.run(TcpAsyncBiDirectionalApplication.class, args);
}
}
#Configuration
class ServerPeer {
private final Set<String> clients = ConcurrentHashMap.newKeySet();
#Bean
public AbstractServerConnectionFactory server(SampleProperties properties) {
return Tcp.netServer(properties.getServerPort()).get();
}
#Bean
public IntegrationFlow serverIn(AbstractServerConnectionFactory server) {
return IntegrationFlows.from(Tcp.inboundAdapter(server))
.transform(Transformers.objectToString())
.log(msg -> "received by server: " + msg.getPayload())
.get();
}
#Bean
public IntegrationFlow serverOut(AbstractServerConnectionFactory server) {
return IntegrationFlows.fromSupplier(() -> "seed", e -> e.poller(Pollers.fixedDelay(5000)))
.split(this.clients, "iterator")
.enrichHeaders(h -> h.headerExpression(IpHeaders.CONNECTION_ID, "payload"))
.transform(p -> "sent by server Hello from server")
.handle(Tcp.outboundAdapter(server))
.get();
}
#EventListener
public void open(TcpConnectionOpenEvent event) {
if (event.getConnectionFactoryName().equals("server")) {
this.clients.add(event.getConnectionId());
}
}
#EventListener
public void close(TcpConnectionCloseEvent event) {
this.clients.remove(event.getConnectionId());
}
}
enter code here
enter code here
TCP/IP is just one of those protocols implemented as channel adapters in Spring Integration.
See more info in the theory: https://www.enterpriseintegrationpatterns.com/ChannelAdapter.html
And here is a list of all the supported protocols in Spring Integration:
https://docs.spring.io/spring-integration/docs/current/reference/html/endpoint-summary.html#spring-integration-endpoints
What those tutorials are talking about is a messaging channel internal to your application logic. It has nothing to do with external protocol, like yours TCP/IP. You just need to understand for your self if your application is going to be client for that IP host/port or it is going to be a server opening respective socket:
https://docs.spring.io/spring-integration/docs/current/reference/html/ip.html#ip

java socket multiple clients not receiving messages

i am making a java socket chat program and i made it compatible for multiple connections and when a user joins it doesn't send the message "[user] Joined" to all clients just to the one that connected but i have a thread for each client if anyone can tell me why it is only sending the message to the user that recently joined i would greatly appreciate it. Here is the server code
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class server {
public ObjectInputStream input;
public ServerSocket server;
public Socket s;
public ObjectOutputStream output;
public ArrayList<Socket> users = new ArrayList<Socket>();
public class Accept implements Runnable {
public void run() {
try {
server = new ServerSocket(55555, 100);
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
s = server.accept();
users.add(s);
new EchoThread(s).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public class EchoThread extends Thread {
private Socket sock;
public EchoThread(Socket s) throws IOException {
this.sock = s;
output = new ObjectOutputStream(sock.getOutputStream());
}
public void run() {
System.out.println(sock.getInetAddress() + " Connected");
try {
for(Socket s: users) {
output.writeObject(s.getInetAddress() + " Connected");
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
server() throws IOException {
Thread t = new Thread(new Accept());
t.start();
}
public static void main(String[] args) throws IOException {
new server();
}
}
So,
Every time someone connects to the server, u create a new EchoThread.
Each User has his own EchoThread.
Your Server role is to manage all the EchoThreads and Sockets.
output.writeObject(s.getInetAddress() + " Connected");
This only sends a message to ONE user.
Your Server should have a List of Sockets and send messages to every Sockets
public ArrayList<Socket> users = new ArrayList<Socket>();
public ArrayList<ObjectOutputStream> outputs = new ArrayList<ObjectOutputStream>();
public class Accept implements Runnable {
public void run() {
try {
server = new ServerSocket(55555, 100);
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
s = server.accept();
users.add(s);
outputs.add(new ObjectOutputStream(s.getOutputStream()));
for (ObjectOutputStream o: outputs) {
o.writeObject(s.getInetAddress() + " has connected");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

I can not connect to server with Socket.IO-client Java

I want use library
And I wan realize this functionality:
connect to my java server
Socket socket = IO.socket("http://127.0.0.1:4444");
socket.io().open(new Manager.OpenCallback() {
#Override
public void call(Exception err) {
if (err != null) {
Log.d("mylog", err.getMessage());
return;
}
Log.d("mylog", "connected");
}
});
Send messge - I do not understand how.
It is my server:
public class Server {
public static void main(String[] args) throws IOException {
System.out.println("Welcome to Server side");
BufferedReader in = null;
PrintWriter out= null;
ServerSocket servers = null;
Socket fromclient = null;
// create server socket
try {
servers = new ServerSocket(4444);
} catch (IOException e) {
System.out.println("Couldn't listen to port 4444");
System.exit(-1);
}
try {
System.out.print("Waiting for a client...");
fromclient= servers.accept();
System.out.println("Client connected");
} catch (IOException e) {
System.out.println("Can't accept");
System.exit(-1);
}
in = new BufferedReader(new
InputStreamReader(fromclient.getInputStream()));
out = new PrintWriter(fromclient.getOutputStream(),true);
String input,output;
System.out.println("Wait for messages");
while ((input = in.readLine()) != null) {
if (input.equalsIgnoreCase("exit")) break;
out.println("S ::: "+input);
System.out.println(input);
}
out.close();
in.close();
fromclient.close();
servers.close();
}
}
If I use Java client I can work with server, but I want to connect to android client. And I found only this library, and I not understand how it work. Examples in site not helped for me.
Make sure you have added its permission in your AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />
Android's kernel, unlike mainline Linux kernel, restricts requests for creating sockets unless that application already has INTERNET permission.
Find more technical information about Android's Paranoid networking option in this link.
UPDATE #1
If you want to connect your Android client to the server on your PC localhost you should not use 127.0.0.1 as server IP address. This is Android its own localhost. You should instead use 10.0.2.2 as server IP address. More Info
#Pavel i've implemented SocketIO client for one of my app
here is the code... i think ..this may help u
private Socket mSocket;
/**
* chat socket connection methods
*/
public void socketConnection()
{
try
{
mSocket = IO.socket(Constant.CHAT_SERVER_URL);
mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
mSocket.on("message", onSocketConnectionListener);
mSocket.connect();
}
catch (URISyntaxException e)
{
e.printStackTrace();
}
new Thread(new Runnable() {
#Override
public void run() {
while(mSocket.connected()==false)
{
//do nothing
}
sendConnectData();
}
}).start();
}
/**
* Send Data to connect to chat server
*/
public void sendConnectData()
{
JSONObject msgToSend=new JSONObject();
try
{
msgToSend.put("Type", 1);
msgToSend.put("userid", userid);
}
catch (Exception e)
{
e.printStackTrace();
}
mSocket.emit("message", msgToSend);
}
/**
* Listener for socket connection error.. listener registered at the time of socket connection
*/
private Emitter.Listener onConnectError = new Emitter.Listener() {
#Override
public void call(Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mSocket != null)
if (mSocket.connected() == false)
socketConnection();
}
});
}
};
/**
* Listener to handle messages received from chat server of any type... Listener registered at the time of socket connected
*/
private Emitter.Listener onSocketConnectionListener = new Emitter.Listener() {
#Override
public void call(final Object... args) {
runOnUiThread(new Runnable() {
#Override
public void run() {
// handle the response args
}
});
}
};

Make sure RMI only operates on one Server instance

I am currently trying to grab the basics of RMI by implementing a Server/Client Structure where both the Client can invoke remote Operations on the Server, and the Server can invoke Client functions:
public class Client extends GenericRMI implements ClientInterface {
public ServerInterface server;
public Client() {
try {
String IP = InetAddress.getLocalHost().getHostAddress();
server = (ServerInterface) Naming.lookup("//192.168.2.124/WServer");
int uniqueID = (int) Math.round(Math.random() * 1000);
super.setUpRMI("WClient" + IP + "_" + uniqueID);
server.registerNewClient(IP, uniqueID);
} catch (Exception e) {
e.printStackTrace();
}
}
public void setUserID(int id) {
System.out.println("got my ID from the server: " + id);
}
}
public class Server extends GenericRMI implements ServerInterface {
private List<ClientInterface> clients;
public Server() {
clients = new ArrayList<ClientInterface>();
super.setUpRMI("WServer");
}
public void registerNewClient(String IP, int uID) throws RemoteException {
try {
ClientInterface c = (ClientInterface) Naming.lookup("//" + IP + "/WClient" + IP + "_"
+ uID);
int newID = clients.size();
clients.add(c);
c.setUserID(newID);
} catch (Exception e) {
e.printStackTrace();
}
}
}
and, in the main function:
new Server();
Thread.sleep(1000);
new Client();
Thread.sleep(1000);
new Client();
Thread.sleep(1000);
new Client();
interfaces are defined by
public interface ServerInterface extends Remote...
RMI setup
public class GenericRMI implements Remote, Serializable {
protected Registry registry;
public void setUpRMI(String bindName) {
if (registry == null) {
try {
registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
} catch (ExportException e) {
// client and server on one PC
} catch (RemoteException e) {
e.printStackTrace();
}
}
try {
Naming.rebind(bindName, this);
} catch (RemoteException | MalformedURLException e) {
e.printStackTrace();
}
System.out.println("Started " + bindName);
}
}
however, output is like
Started WServer
Started WClient192.168.2.124_501
got my ID from the server: 0
Started WClient192.168.2.124_655
got my ID from the server: 0
Started WClient192.168.2.124_771
got my ID from the server: 0
even if i debug it, the server has a different ID for each client. I guess I am doing a terrible mistake somewhere, since I used to think that the server would only have ONE instance running. How can I achieve that?
EDIT
the Problem is; if i debug the registerNewClient() function, the respective Server object changes for each Client:
Server#7728992
Server#5fbb71ac
...
Even if i make the clients' list synchronized, it doesn't help. However, making the clients field transient server-side leads to a null pointer exception on it, indicating that it indeed is a new instance.
You do have only one instance running. You only called new Server() once, and in any case there's no way three instances can be bound to the same name in the Registry. More likely you have a concurrency problem on the unsynchronized 'clients' collection.

Infinite loop when deploying OSGI bundle with network server

I'm trying to implement OSGI bundle with network server which uses network sockets.
This is the complete source code: http://www.2shared.com/file/RMXby331/CB_27.html
This is the Activator:
package org.DX_57.osgi.CB_27.impl;
import java.util.Properties;
import org.DX_57.osgi.CB_27.api.CBridge;
import org.DX_57.osgi.CB_27.impl.EchoServer;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
public class CBridgeApp implements BundleActivator {
public void start(BundleContext bc) throws Exception {
ServiceRegistration registerService = bc.registerService(CBridge.class.getName(), new CBridgeImpl(), new Properties());
EchoServer();
}
public void stop(BundleContext bc) throws Exception {
boolean ungetService = bc.ungetService(bc.getServiceReference(CBridge.class.getName()));
}
private void EchoServer() {
EchoServer method = new EchoServer();
}
}
This is the source code if the Java Network server:
package org.DX_57.osgi.CB_27.impl;
import java.net.*;
import java.io.*;
public class EchoServer
{
ServerSocket m_ServerSocket;
public EchoServer()
{
try
{
// Create the server socket.
m_ServerSocket = new ServerSocket(12111);
}
catch(IOException ioe)
{
System.out.println("Could not create server socket at 12111. Quitting.");
System.exit(-1);
}
System.out.println("Listening for clients on 12111...");
// Successfully created Server Socket. Now wait for connections.
int id = 0;
while(true)
{
try
{
// Accept incoming connections.
Socket clientSocket = m_ServerSocket.accept();
// accept() will block until a client connects to the server.
// If execution reaches this point, then it means that a client
// socket has been accepted.
// For each client, we will start a service thread to
// service the client requests. This is to demonstrate a
// multithreaded server, although not required for such a
// trivial application. Starting a thread also lets our
// EchoServer accept multiple connections simultaneously.
// Start a service thread
ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
cliThread.start();
}
catch(IOException ioe)
{
System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
}
public static void main (String[] args)
{
new EchoServer();
}
class ClientServiceThread extends Thread
{
Socket m_clientSocket;
int m_clientID = -1;
boolean m_bRunThread = true;
ClientServiceThread(Socket s, int clientID)
{
m_clientSocket = s;
m_clientID = clientID;
}
public void run()
{
// Obtain the input stream and the output stream for the socket
// A good practice is to encapsulate them with a BufferedReader
// and a PrintWriter as shown below.
BufferedReader in = null;
PrintWriter out = null;
// Print out details of this connection
System.out.println("Accepted Client : ID - " + m_clientID + " : Address - " +
m_clientSocket.getInetAddress().getHostName());
try
{
in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(m_clientSocket.getOutputStream()));
// At this point, we can read for input and reply with appropriate output.
// Run in a loop until m_bRunThread is set to false
while(m_bRunThread)
{
// read incoming stream
String clientCommand = in.readLine();
System.out.println("Client Says :" + clientCommand);
if(clientCommand.equalsIgnoreCase("quit"))
{
// Special command. Quit this thread
m_bRunThread = false;
System.out.print("Stopping client thread for client : " + m_clientID);
}
else
{
// Echo it back to the client.
out.println(clientCommand);
out.flush();
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
// Clean up
try
{
in.close();
out.close();
m_clientSocket.close();
System.out.println("...Stopped");
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
}
}
}
}
When I try to deploy the bundle on Glassfish server the application server hangs but I can connect to the java network server using the java client. It seems that there is a infinite loop. I need help to fix the code.
Best wishes
Your bundle activator start method never returns, because you're calling constructor of your service with infinite loop. A good practice is to return as fast as possible from bundle activators.
Here is an idea how to rewrite your code:
public class EchoServer {
private volatile boolean started;
public void start() {
new Thread(new Runnable() {
#Override
public void run() {
started = true;
try {
m_ServerSocket = new ServerSocket(12111);
} catch(IOException ioe) {
System.out.println("Could not create server socket at 12111. Quitting.");
System.exit(-1);
}
System.out.println("Listening for clients on 12111...");
// Successfully created Server Socket. Now wait for connections.
int id = 0;
while (started) {
try {
Socket clientSocket = m_ServerSocket.accept();
ClientServiceThread cliThread = new ClientServiceThread(clientSocket, id++);
cliThread.start();
} catch(IOException ioe) {
System.out.println("Exception encountered on accept. Ignoring. Stack Trace :");
ioe.printStackTrace();
}
}
}
}).start();
}
public void stop() {
started = false;
}
}
Activator
public class CBridgeApp implements BundleActivator {
private EchoServer method;
public void start(BundleContext bc) throws Exception {
...
method = new EchoServer();
method.start();
}
public void stop(BundleContext bc) throws Exception {
...
method.stop();
}
}

Categories