Sending ByteArray using Java Sockets (Android programming) - java

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.

Related

Simple UDP link

Hallo I need to write a very simple app that sends and retrieve data trough an UDP link (on Android OS, API level > 18):
This's a piece of code I used in an application I wrote sometime ago to connect trough TCP/IP (and doing the same thing):
class LinkReader implements Runnable
{
private final int mPort;
private final String mAddress;
private final Socket mLinkSocket;
public LinkReader(String address, int port, Socket link_socket)
{
mLinkSocket = link_socket;
mPort = port;
mAddress = address;
}
#Override
public void run()
{
try {
BufferedReader input = new BufferedReader(
new InputStreamReader(
mLinkSocket.getInputStream()
)
);
while (true)
{
Thread.sleep(100);
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
class LinkThread implements Runnable {
private final int mPort;
private final String mAddress;
private Socket mLinkSocket;
public LinkThread(String address, int port, Socket socket)
{
mLinkSocket = socket;
mPort = port;
mAddress = address;
}
#Override
public void run()
{
try
{
mLinkSocket = new java.net.Socket(
InetAddress.getByName(mAddress),
mPort
);
new Thread(new LinkReader(mAddress,mPort,mLinkSocket)).start();
}
catch (UnknownHostException e) {
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private void sendCommand(String cmd, Socket socket)
{
try
{
PrintWriter _out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()
)
),
false
);
_out.print(cmd);
_out.flush();
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
I've not been able to find an example about UDP connection on Android OS and I tought to reuse this code mainly because it was working pretty good (but I have to admint that I had not a very deep knowlede of Android neither I had very hight performances expectations from this piece of code).
Besides it was working in my past application my question is it correct now, in terms of code structure and aging?
How can I modify this to establish an UDP connection?
BTW Up to now I don't need really a R/W connection (I just need to send commands over there).

Separating Client class from JFrame [duplicate]

A few days ago i tried to create a server - client or client Server as an experiment to learn about socket using a thread but then someone told me that i should use swingWorker. I did some research how to use and have implemented it in as practice but it still doesn't work. the swingWorker thread doesn't look like it is running even tho i get a connection and have used .excute(). If you guys can help spot where i am doing wrong that will be great. SwingWorker class is in the startSever() and startClient() method.
private void startServer() {
SwingWorker <Void, String> runningServer = new SwingWorker<Void, String>(){
protected Void doInBackground() {
try {
listeningSocket = new ServerSocket(port);
System.out.println("waiting for connection");
connection = listeningSocket.accept();
connected = true;
System.out.println("Connected");
String incomeMessage =null;
while(connected){
inStream = connection.getInputStream();
inDataStream = new DataInputStream(inStream);
if (myMessage !=null){
outStream = connection.getOutputStream();
outDataStream = new DataOutputStream(outStream);
outDataStream.writeUTF(myMessage);
}
if((incomeMessage = inDataStream.readUTF())!=null){
clientMessage = incomeMessage;
publish(clientMessage);
incomeMessage =null;
}
}
} catch (IOException e) {
clientMessage = "Connection Lost";
}
return null;
}
runningServer.execute();
}
Here's a VERY basic example.
Basically, because you program requires asynchronous communications (that is, you need to be able to read from the socket AND write to it at the same time), you need to offload each stream to a separate thread.
The management process of this example is, well, no existent. Realistically, you should have some kind of "connection" manager that would be able to cleanly close the output and input threads so that, for example, when the user types "bye", the output thread would be able to tell the connection manager that the connection should be terminated. It would then tell the input thread to stop reading any new message and terminate...
Client
public class Client {
public static void main(String[] args) {
try {
Socket master = new Socket("localhost", 8900);
new Thread(new InputHandler(master)).start();
new Thread(new OuputHandler(master)).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static class InputHandler implements Runnable {
private Socket socket;
public InputHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
boolean commune = true;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (commune) {
String text = reader.readLine();
System.out.println("\n<server> " + text);
if (text.toLowerCase().equals("bye")) {
commune = false;
}
}
} catch (Exception exp) {
exp.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
}
try {
socket.close();
} catch (Exception e) {
}
}
}
}
public static class OuputHandler implements Runnable {
private Socket socket;
public OuputHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
boolean commune = true;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner scanner = new Scanner(System.in);
while (commune) {
System.out.print("> ");
String text = scanner.nextLine();
writer.write(text);
writer.newLine();
writer.flush();
if (text.equalsIgnoreCase("bye")) {
commune = false;
}
}
} catch (Exception exp) {
exp.printStackTrace();
} finally {
try {
writer.close();
} catch (Exception e) {
}
try {
socket.close();
} catch (Exception e) {
}
}
}
}
}
Server
public class Server {
public static void main(String[] args) {
try {
ServerSocket master = new ServerSocket(8900);
Socket socket = master.accept();
new Thread(new InputHandler(socket)).start();
new Thread(new OuputHandler(socket)).start();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static class InputHandler implements Runnable {
private Socket socket;
public InputHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
boolean commune = true;
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (commune) {
String text = reader.readLine();
System.out.println("\n<client> " + text);
if (text.toLowerCase().equals("bye")) {
commune = false;
}
}
} catch (Exception exp) {
exp.printStackTrace();
} finally {
try {
reader.close();
} catch (Exception e) {
}
try {
socket.close();
} catch (Exception e) {
}
}
}
}
public static class OuputHandler implements Runnable {
private Socket socket;
public OuputHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
boolean commune = true;
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner scanner = new Scanner(System.in);
while (commune) {
System.out.print("> ");
String text = scanner.next();
writer.write(text);
writer.newLine();
writer.flush();
if (text.equalsIgnoreCase("bye")) {
commune = false;
}
}
} catch (Exception exp) {
exp.printStackTrace();
} finally {
try {
writer.close();
} catch (Exception e) {
}
try {
socket.close();
} catch (Exception e) {
}
}
}
}
}
Update (whine)
While I have your source code in front of me...
There should very, very, rarely be a need to do textMessage.addKeyListener(this)
Because you are using a JTextField, you should be using a ActionListener instead. There are a a number of important reasons for this, but for you, the main one would be the fact that a "accept" action is Look and Feel dependent. While most systems do use Enter as there "accept" action, is not a guarantee.
Have a look at How to Write a Action Listener for more information
Given the general complexity of what you are trying to do, +1 for a overall good attempt!
Using this example, the following changes work with a single telnet client.
private PrintWriter out;
...
public void keyPressed(KeyEvent e) {
if (e.getKeyChar() == KeyEvent.VK_ENTER) {
myMessage = friendLabel + textMessage.getText();
if (out != null) {
out.println(myMessage);
}
...
}
...
protected Void doInBackground() {
try {
listeningSocket = new ServerSocket(port);
System.out.println("Waiting for connection");
connection = listeningSocket.accept();
connected = true;
System.out.println("Connected");
Scanner in = new Scanner(connection.getInputStream());
out = new PrintWriter(connection.getOutputStream(), true);
publish("Connected");
while (true) {
publish(in.nextLine());
}
} catch (IOException e) {
clientMessage = "Connection Lost";
try {
connection.close();
System.out.println("Closed");
} catch (IOException e1) {
e1.printStackTrace();
connected = false;
}
}
return null;
}
I see your server port is 8900 and your client port is 8900 too. I am not sure if it matters if the server and client are running on the same machine...

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.

Udp client thread not reusable

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 :)

NullPointerException when receiving an array list over a socket

Trying to send an arrayList over a socket, get a null pointer exception at object input stream initialization (client).
Client:
try {
ObjectInputStream objIn = new ObjectInputStream(
Client.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
Server:
try {
ObjectOutputStream objOut = new ObjectOutputStream(
this.client.getOutputStream());
objOut.writeObject(library);
objOut.flush(); // added later, not helping
}
I've been trying to comunicate over sockets for two days now with almost no success. I have no idea what's going on. Ofc I plan to document myself better when I'll have more time but for now I'd really like to understand what is happening.
EDIT
public class Client {
private static int port = 6666;
private static Socket socket = null;
public Client (int port) {
Client.port = port;
}
public Client () {
}
public void establishConnection() {
try {
Client.socket = new Socket(InetAddress.getByName(null), Client.port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Server:
public void start () {
(new Thread() {
public void run() {
try {
Server.socket = new ServerSocket(Server.portNumber);
while (!Server.stop) {
Socket client = Server.socket.accept();
(new HandleRequest (client)).start();
}
...............
public class HandleRequest extends Thread {
private Socket client = null;
private SQL sql_db = new SQL ();
public HandleRequest (Socket client) {
this.client = client;
}
#Override
public void run () {
try {
if (!this.sql_db.isConnected())
this.sql_db.connect();
if (this.client == null) {
System.out.println("Error: client does not exist, NO idea what's going on");
return;
}
ArrayList<Book> library = this.sql_db.getAllBooks();
try {
ObjectOutputStream objOut = new ObjectOutputStream(
this.client.getOutputStream());
objOut.writeObject(library);
objOut.flush();
} catch (Exception e) {
System.out.println("Server error in handling request for whole library!");
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Because the NPE is on this line:
Client.socket.getInputStream());
there is only one thing that can cause it. It can't be Client, because that is static. It can't be getInputStream(), because that is a method, so it has to be socket that is causing the NPE.
On this line:
private static Socket socket = null;
you set socket to be null. The only place I see where you set it to be not null is in your .establishConnection() method, but I don't see where you call that method.
Therefore, your problem is most likely that you aren't calling the .establishConnection() method.
Is you establishConnection method called before
try {
ObjectInputStream objIn = new ObjectInputStream(
Client.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
If not, your Client.socket is null and you need to initialize it. I.e. your code should look like this:
try {
Client c = new Client(1337);
c.establishConnection();
ObjectInputStream objIn = new ObjectInputStream(
c.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {

Categories