Udp client thread not reusable - java

I'm developing a simple UDP communication software to communicate with my robot.
I've been able to use this code to send the first packet but when I try to send the second it does not send neither does it give me errors, what did I do wrong?
EDIT : The problem is I can't use the send void twice.
Code :
Send Void:
public static void Send(String Message)
{
Client Clt = new Client();
Clt.Message = Message;
Clt.start();
}
Client :
public class Client extends Thread {
public String Message;
public void run()
{
PrintStream myPS = null;
try {
myPS = new PrintStream(Start.CltSkt.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
myPS.println(Message);
try {
finalize();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
EDIT 2 (Problem Solved) :
thanks to everyone that answered/commented the questions especially to EJP.
The problem was :
I was not using a DatagramSocket so I ended up with this :
public static void Send(String Message)
{
InetAddress Ip = null;
DatagramSocket datagramSocket = null;
try {
datagramSocket = new DatagramSocket();
} catch (SocketException ex) {
Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] buffer = Message.getBytes();
DatagramPacket packet;
try {
Ip = InetAddress.getByName(CltIp);
} catch (UnknownHostException ex) {
Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex);
}
packet = new DatagramPacket(buffer, buffer.length, Ip, Integer.parseInt(CltPort));
try {
datagramSocket.send(packet);
} catch (IOException ex) {
Logger.getLogger(Start.class.getName()).log(Level.SEVERE, null, ex);
}
}
I was not awere of the the use with datagram sockets! Now I'm :)

Related

Sending ByteArray using Java Sockets (Android programming)

I have this Java code that sends string with Socket. I can use the same code for Android.
public class GpcSocket {
private Socket socket;
private static final int SERVERPORT = 9999;
private static final String SERVER_IP = "10.0.1.4";
public void run() {
new Thread(new ClientThread()).start();
}
public int send(String str) {
try {
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),
true);
out.println(str);
out.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return str.length();
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
Now, I need to send binary information encoded in ByteArray.
What might be the best ways to do this? I'm considering converting the ByteArray into string to use the same method, but I guess one can send the byte array information directly using Java Sockets.
just call write(byte[] a) on the OutputStream the one you get from the socket.

read packet from tcp socket in java with acknoledgement

We are creating a java listener to read multiple device data those are configured on particular server ip and port.Device following below rule.
device send a login packet.
server will return ack packet in response.
after receive ack device will send information packet.
server reads that data.
on last step we stuck, we are sending the ack but cant get the information packet back from device(though we check the generated ack through opensource sofware).For ref we are attaching code.(if we remove while(true) than get login packet but after that socket connection will close and again device will send login packet but if we keep it then we dont get any packet)
//--------------Main class------------------------------------------
public class Main {
public static void main(String[] args) {
Server server = new Server(listen_port, pool_size, pm);
new Thread(server).start();
logger.info("Server Started .....");
}
}
//--------------------------------------------------------------
public class Server implements Runnable {
private ServerSocket serverSocket = null;
public void run()
{
this.m_stop = false;
while (!this.m_stop)
try {
this.m_pool.execute(new Handler(this.serverSocket.accept()));
} catch (IOException e) {
LOGGER.debug("Unable to accept connection ", e);
}
}
}
//--------------------------------------------------------------
public class Handler implements Runnable {
private Socket m_clientSocket;
private String imei;
public Handler(Socket socket) {
this.m_clientSocket = socket;
}
public void run() {
DataOutputStream clientDataOS = null;
DataInputStream clientDataIS = null;
try {
logger.info("data is coming");
m_clientSocket.setSoTimeout(300000);
clientDataIS = new DataInputStream(this.m_clientSocket.getInputStream());
clientDataOS = new DataOutputStream(this.m_clientSocket.getOutputStream());
while (true) {
String pkt = "";
logger.info("Waiting for input strem");
byte[] byte_pkt = IOUtils.toByteArray(clientDataIS);
logger.info("Got input stream");
for (byte b : byte_pkt) {
pkt += String.format("%02X ", b);
}
logger.info(pkt);
if (byte_pkt.length > 0) {
logger.info("");
if (Byte.valueOf(byte_pkt[3]) == 1) {
imei = "xyz";
logger.info("login packet");
byte[] rep_pkt = Utils.getReceptionPacket(byte_pkt);//send back to device
clientDataOS.write(rep_pkt);
clientDataOS.flush();
} else if (Byte.valueOf(byte_pkt[3]) == 34) {
logger.info("information packet");
Utils.processPackets(byte_pkt);
} else {
logger.info("Unkown packet format");
}
logger.info(imei);
} else {
logger.info("InputStream is empty.");
}
}
} catch (SocketException se) {
logger.error("Failure on reading data", se);
} catch (IOException e) {
logger.error("Failure on reading data", e);
} catch (Exception e) {
logger.error("Error while processing data", e);
} finally {
try {
IOUtils.closeQuietly(clientDataOS);
IOUtils.closeQuietly(clientDataIS);
this.m_clientSocket.close();
} catch (IOException e) {
logger.debug("Error when sending out response ::", e);
}
}
}
}

client/server connection closing causes loop error

I got to stage where client and server communicate, sending messages from and to each other.
The problem I am having is how to close the connection without causing an error?
If I terminate one of the apps (either server or client) that causes the connection to be lost, and then it causes the loop that is waiting for input to loop indefinitely and showing null's.
I tried closing sockets, buffers and even the thread, didn't work.
This is the client side
public void onClick(View view) {
try {
EditText et = (EditText) findViewById(R.id.EditText01);
String str = et.getText().toString();
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println(str);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
class ClientThread implements Runnable {
#Override
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
socket = new Socket(serverAddr, SERVERPORT);
CommunicationThread commThread = new CommunicationThread(socket);
new Thread(commThread).start();
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
This is the server side
class ServerThread implements Runnable {
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SERVERPORT);
} catch (IOException e) {
e.printStackTrace();
}
while (!Thread.currentThread().isInterrupted()) {
try {
socket = serverSocket.accept();
CommunicationThread commThread = new CommunicationThread(
socket);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Both use these classes:
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(
this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
String read = input.readLine();
updateConversationHandler.post(new updateUIThread(read));
//***HERE EXTRA BIT FOR THE SERVER
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class updateUIThread implements Runnable {
private String msg;
public updateUIThread(String str) {
this.msg = str;
}
#Override
public void run() {
text.setText(msg);
}
}
the only difference is the server has this bit where it says above ***HERE EXTRA BIT FOR THE SERVER
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
out.println("Message recieved");
so basically, client connects, server accepts, then client sends message, servers receives message and shows it, and then sends "Message received" to the client, and the client shows it.
All this works fine, but once the connection is lost, they hang on showing null repeatedly, and I have to force the app to close.
You aren't checking for end of stream. If readLine() returns null, the peer has closed the connection, and you must do likewise and stop reading.
It's hard to believe you really need a new thread for every line to update the UI.

Connect to remote port(Server) from thread in polling

I want to connect to a remote server from thread and keep sending strings. If the connection gets refused the thread should keep polling the port until the server is up again. How can I handle this exception and keep my thread fro crashing? The server may not be up for long time but thread should run indefinitely.
public void SendMessage(String message){
try {
socket = new Socket(actuatorAddress, destPort.get());
outToServer = socket.getOutputStream();
out = new DataOutputStream(outToServer);
out.flush();
out.write(message.getBytes());
} catch (IOException ex) {
System.out.println(ex.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
I changed some part of the code as below. For first time called Connect function and then subsequently called Send Message function through thread. The delay added to reconnecting helped reduce time lag recurred due to connecting to non existing server. Still think that there might be a better solution to the basic problem.
public boolean ConnectToActuator() {
try {
if(actuatorAddress.isReachable(2000)){
socket = new Socket();
socket.setPerformancePreferences(1, 2, 0);
socket.setTcpNoDelay(false);
socket.setSendBufferSize(32);
socket.connect(new InetSocketAddress(actuatorAddress, destPort.get()));
outToServer = socket.getOutputStream();
out = new DataOutputStream(outToServer);
connected = true;
disconnectedTimeout = 0;
}
}catch (ConnectException e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
}catch (IOException ex) {
connected = false;
System.out.println(ex.getMessage());
}
return connected;
}
public boolean SendToActuator(String message) {
if(connected == false){ //socket.isOutputShutdown()
disconnectedTimeout++;
if(disconnectedTimeout>20){
disconnectedTimeout = 0;
ConnectToActuator();
} else {
return connected;
}
}
try {
out.flush();
out.writeBytes(message);
disconnectedTimeout = 0;
connected = true;
} catch (UnknownHostException uhe) {
connected = false;
System.out.println(uhe.getMessage());
} catch (IOException ioe) {
connected = false;
System.out.println(ioe.getMessage());
}
return connected;
}
Given the following constraints in the comments:
Try to send the message to one of the 10 servers.
If none of the servers are available to receive the message, discard the message.
What you actually want to do is:
Iterate through a list of server addresses
Attempt to send a message to each of them
Break out of the loop right away if successful
Catch any errors on connection failure and try the next server
Here's an example class that will run through that scenario.
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class MessageSender {
private static final Integer destPort = 1234;
private static final String[] serverAddresses = {
"address1",
"address2",
"address3" // Etc....
};
public Boolean SendMessage(String message) {
Boolean messageSentSuccessfully = false;
for (String addy : serverAddresses) {
messageSentSuccessfully = SendMessageToServer(addy, message);
if (messageSentSuccessfully) {
break;
}
}
return messageSentSuccessfully;
}
private Boolean SendMessageToServer(String serverAddress, String message) {
Boolean messageSent = false;
try {
Socket dataSocket = new Socket(serverAddress, destPort);
OutputStream outToServer = dataSocket.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.write(message.getBytes());
out.flush();
messageSent = true;
} catch (Exception e) {
System.out.println(e);
}
return messageSent;
}
}
Hope that helps.
Pseudo:
while(true){
if(connect()) DoClientConnectedStuff();
sleep(reconnectTimeout);
};
please try below changes. if your connection refuses it will wait for 2s(2000ms) and then again try to connect with server. if connection being successful it will take outputstream, write data in a while loop and flush the data.
public void createSocketConnection() throws IOException
{
socket = new Socket(actuatorAddress, destPort.get());
if(socket!=null)
{
outToServer = socket.getOutputStream();
out = new DataOutputStream(outToServer);
}
}
public void SendMessage(String message){
boolean isRunning=false;
try
{
createSocketConnection();
isRunning=true;
while(isRunning)
{
out.write(message.getBytes());
out.flush();
}
} catch (java.net.ConnectException conExcp) {
System.out.println(ex.getMessage());
try{
Thread.sleep(2000);
}catch(Exception ee){}
}
catch (IOException ex) {
System.out.println(ex.getMessage());
}
}

Server is only reading the first object that is sent from the client

I'm having issues sending objects to a server. Right now, I have a server setup and listening for clients. The client connects, sends a test object (just a String) and outputs it to the command line. It works for the first string sent but none after that.
Server (Hivemind.java):
// Open server socket for listening
ServerSocket ss = null;
boolean listening = true;
try {
ss = new ServerSocket(PORT_NUMBER);
} catch (IOException e) {
System.err.println("Cannot start listening on port " + PORT_NUMBER);
e.printStackTrace();
}
// While listening is true, listen for new clients
while (listening) {
Socket socket = ss.accept();
ServerDispatcher dispatcher = new ServerDispatcher(socket);
dispatcher.start();
}
// Close the socket after we are done listening
ss.close();
Server Thread (ServerDispatcher):
public ServerDispatcher(Socket socket) {
super("ServerDispatcher");
this.socket = socket;
}
public void run() {
System.out.println("Client connected");
try {
input = socket.getInputStream();
objInput = new ObjectInputStream(input);
Object obj = null;
try {
obj = (String)objInput.readObject();
} catch (ClassNotFoundException ex) {
Logger.getLogger(ServerDispatcher.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(obj);
} catch (IOException ex) {
Logger.getLogger(ServerDispatcher.class.getName()).log(Level.SEVERE, null, ex);
}
Connection Class (HivemindConnect.java):
public HivemindConnect(int port) {
this.port = port;
url = "localhost";
}
public HivemindConnect(int port, String url) {
this.port = port;
this.url = url;
}
public void connect() {
try {
socket = new Socket(url, port);
output = socket.getOutputStream();
objOutput = new ObjectOutputStream(output);
} catch (IOException e) {
e.printStackTrace();
}
}
public void close() {
try {
objOutput.close();
output.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void send(Object obj) {
try {
objOutput.writeObject(obj);
objOutput.flush();
} catch (IOException ex) {
Logger.getLogger(HivemindConnect.class.getName()).log(Level.SEVERE, null, ex);
}
}
CustomerTopComponent:
// When the TC is opened connect to the server
#Override
public void componentOpened() {
hivemind = new HivemindConnect(9001);
hivemind.connect();
}
private void btnSendActionPerformed(java.awt.event.ActionEvent evt) {
hivemind.send(txtText.getText());
}
// When the TC is closed close the connection to the server
#Override
public void componentClosed() {
hivemind.close();
}
You need a loop like this:
while(objInput.available()>0){
Object obj = null;
obj = (String)objInput.readObject();
System.out.println(obj);}
Or something similar.

Categories