Here is my goal. I am designing a server that will spit out data every second. I need to also design a client (on android) that will connect to that server and gather the data that is being sent by the server. I have already wrote up some code for this in java and for the android. However, my experience with java and android is very minimal. I have been having a lot of difficulty with this but have started making progress. I was wondering if everyone could take a look at my code and give some tips on how to best perform this design.
The server will just be constantly spitting out data and the client will connect to the server and then start gathering the data that is being sent.
The data that is being sent is not important. Right now it will just be something random for testing.
Thanks in advance!
THE JAVA SERVER
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class SmartServerSocket {
private ServerSocket server;
private int port = 7777;
public SmartServerSocket() {
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SmartServerSocket smart = new SmartServerSocket();
smart.handleConnection();
}
public void handleConnection() {
// TODO Auto-generated method stub
System.out.println("Waiting for client message...");
while (true) {
try {
Socket socket = server.accept();
new ConnectionHandler(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable {
private Socket socket;
public ConnectionHandler(Socket socket) {
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run() {
ObjectOutputStream oos = null;
int test = 0;
try {
while(true)
{
oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(Integer.toString(test));
test++;
System.out.println("Waiting for client message...");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
THE ANDROID CLIENT
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
//import android.app.Activity;
public class ConnectDevice implements Runnable {
public void run(){
try {
System.out.println("test1");
//InetAddress host = InetAddress.getLocalHost();
InetAddress host = InetAddress.getByName("THEIPADDRESS");
Socket socket = new Socket(host.getHostName(), 7777);
System.out.println("test2");
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
System.out.println("test3");
String message = (String) ois.readObject();
System.out.println("test4");
System.out.println("Message: " + message);
ois.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
I'm using Apache Mina to handle my game's connection. You should take a look on it. It have really made my life easier.
Related
My client doesn't process commands sent from server, but my server can proces commands that client sends. If I run my client in debug than thread "in" is waiting for input string and command proceesed.
I reduced my code for easy reading.
Server:
public class Server extends Thread{
BufferedReader in;
PrintWriter out;
ServerSocket server;
Socket client = null;
Frame frame;
Server() throws IOException{
frame = new Frame();
try {
server = new ServerSocket(4444);
frame.textAreaForServer.append("Welcome to server side!\n");
} catch (IOException e) {
frame.textAreaForServer.append("Couldn't listen to port 4444\n");
System.exit(-1);
}
addListenerOnTextField();
this.start();
}
private void clearVector(){
frame.textAreaForServer.append("-clr\n");
try {
//send message for client
out.println("-clr");
frame.textAreaForServer.append("Vector is cleared\n");
} catch (NullPointerException e1) {
frame.textAreaForServer.append("It's impossible to perform!\n");
}
}
public void run(){
while (true) {
try {
//connection to client
if (client == null) {
frame.textAreaForServer.append("Waiting for client connection...\n");
client = server.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
frame.textAreaForServer.append("Client connected\n");
}
} catch (IOException e) {
frame.textAreaForServer.append("Can't accept\n");
System.exit(-1);
}
}
}
Client:
public class Client extends Thread{
Socket fromserver = null;
BufferedReader in = null;
PrintWriter out;
ControlPanel controlPanel;
Client(ControlPanel controlPanel1) throws IOException {
controlPanel = controlPanel1;
addListenerOnTextField();
this.start();
}
//connection to server
private void connect(ControlPanel controlPanel) {
controlPanel.textAreaForClient.append("-ct\n");
if (fromserver == null) {
controlPanel.textAreaForClient.append("Connecting to localhost...\n");
try {
fromserver = new Socket("localhost", 4444);
in = new BufferedReader(new InputStreamReader(fromserver.getInputStream()));
out = new PrintWriter(fromserver.getOutputStream(), true);
} catch (IOException e1) {
controlPanel.textAreaForClient.append("Server is not available!\n");
}
} else {
controlPanel.textAreaForClient.append("Already connected\n");
}
}
public void run() {
while (true) {
//here the -clr command sent from server should be proceeded, but it doesn't
try {
switch (in.readLine()) {
case "-clr": {
VectorOfThreads.getInstance().getVectorOfThreads().removeAllElements();
controlPanel.textAreaForClient.append("Vector is cleared\n");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
It seems that in client class you forgot to connect to server before reading any Input Stream. And furthermore you didn't call the ClearVector after creating output Stream in Server thread.
I have implemented a very basic Server/Client program based on your code. and it works fine:
Server class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import jdk.internal.org.objectweb.asm.tree.analysis.Frame;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Emad
*/
public class Server extends Thread {
BufferedReader in;
PrintWriter out;
ServerSocket server;
Socket client = null;
Frame frame;
Server() throws IOException {
try {
server = new ServerSocket(4444);
System.out.println("Welcome to server side. listening on port 4444");
} catch (IOException e) {
System.out.println("Couldn't listen to port 4444\\n");
System.exit(-1);
}
this.start();
}
private void clearVector() {
System.out.println(" -clr command send\n");
try {
//send message for client
out.println("-clr");
System.out.println("Vector is cleared\n");
} catch (NullPointerException e1) {
System.out.println("It's impossible to perform\n");
}
}
public void run() {
while (true) {
try {
//connection to client
if (client == null) {
System.out.println("Waiting for client connection...\\n");
client = server.accept();
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
clearVector();
System.out.println("Client Connected!");
}
} catch (IOException e) {
System.out.println("Can't accept.\n");
System.exit(-1);
}
}
}
public static void main(String args[])
{
try {
Server serverInstance = new Server();
} catch (IOException ex) {
System.out.println("Exception");
Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Client class:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* #author Emad
*/
public class Client extends Thread {
Socket fromserver = null;
BufferedReader in = null;
PrintWriter out;
Client() throws IOException {
this.start();
}
//connection to server
private void connect() {
System.out.println("-ct\n");
if (fromserver == null) {
System.out.println("Connecting to localhost...\n");
try {
fromserver = new Socket("localhost", 4444);
in = new BufferedReader(new InputStreamReader(fromserver.getInputStream()));
out = new PrintWriter(fromserver.getOutputStream(), true);
} catch (IOException e1) {
System.out.println("Server is not available!\n");
}
} else {
System.out.println("Already connected\n");
}
}
public void run() {
connect();
while (true) {
//here the -clr command sent from server should be proceeded, but it doesn't
try {
switch (in.readLine()) {
case "-clr": {
System.out.println("Vector is cleared\n");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String args[])
{
try {
Client clientInstance = new Client();
} catch (IOException ex) {
System.out.println("Error in instanciating client");
}
}
}
I'm trying to create a client/server connection and am still quite new to java as well. So the error I am getting tells me that the socket is closed. Following some work, I've managed to write the given code below. I do believe there is something wrong with the way I pass the socket to the connection class, if I had to guess, that causes the socket object to possibly be closed?
I've tried adding waits just in case the server thread hadn't been executed but that didn't seem to affect anything. Maybe I should launch the server with its own launcher in its own command prompt, but I thouht this should work just fine to test the client and server.
I can't seem to find out why my socket is closed before I send my message. Any insights would be greatly appreciated!
Thanks!
Error
java.net.SocketException: Socket is closed
at java.net.Socket.getInputSTream(Unknown Source)
at Connection.run(Connection.java:17)
Server.java
//main calling snippet.
import java.lang.Thread;
public class Server {
public static void main(String[] args) {
if(args.length != 1) {
System.err.println("Usage: java Server <port number>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
Thread server = new KServer(port);
server.start();
//added waits just to make sure the thread was executed?
//thinking this might be my problem
long t = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < t) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
KClient client = new KClient("127.0.0.1",port);
while (!(client.openConn())) {
System.out.println("Failed to connect. Retrying...");
}
client.send("Hello World");
client.closeConn();
}
}
KServer.java
//the actual server class that manages listening and threading the sockets
import java.net.*;
import java.io.*;
public class KServer extends Thread {
private int port;
private ServerSocket sSock;
public KServer(int thisPort) {
port = thisPort;
try {
sSock = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while(true) {
try (Socket cSock = sSock.accept();) {
Thread con = new Connection(cSock);
con.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Connection.java
//Manages sending and receiving messages
import java.net.Socket;
import java.io.*;
public class Connection extends Thread {
Socket socket;
public Connection(Socket s) {
socket = s;
}
public void run() {
String msg;
BufferedReader in;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while((msg = in.readLine()) != null) {
System.out.println(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
KClient.java
//manages the clients connection life to the server
import java.net.*;
import java.io.*;
public class KClient {
private Socket sock;
private String dest;
private int port;
private OutputStreamWriter out;
public KClient(String dst,int prt) {
dest = dst;
port = prt;
}
public boolean openConn() {
try {
sock = new Socket(dest,port);
out = new OutputStreamWriter(sock.getOutputStream(),"ISO-8859-1");
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public void send(String msg) {
try {
out.write(msg);
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
public void closeConn() {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Don't use try-with-resources to accept the socket. It wil close the accepted socket, which needs to stay open so the handling thread can use it. The handling thread is responsible for closing it.
I am trying to code a chat in my java software,
i have 2 eclipses running on my windows 7.
one of the eclipses includes a project "ServerListener" which contains a class Server.java
and the other eclipse includes a project "Client" and contains a class cl.java.
I am sending messages from my cl.java to the server.java
each time the server receives a message he send it back to the cl.java (the one i sent the message from) to make sure it's connected.
(THIS PART WORKS FINE sending message to the server and back from the server to the same client)
my question is :
how to let the server.java send the message to another client instead of the original client?
if i run another eclipse with the same project as "Client"
i want to the two eclipses to chat together
this is the Server.java:
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class Server {
ServerSocket serverSocket;
ArrayList<ServerThread> allClients = new ArrayList<ServerThread>();
public static void main(String[] args) {
new Server();
}
public Server() {
// ServerSocket is only opened once !!!
try {
serverSocket = new ServerSocket(6000);
System.out.println("Waiting on port 6000...");
boolean connected = true;
// this method will block until a client will call me
while (connected) {
Socket singleClient = serverSocket.accept();
// add to the list
ServerThread myThread = new ServerThread(singleClient);
allClients.add(myThread);
myThread.start();
}
// here we also close the main server socket
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ServerThread extends Thread {
Socket threadSocket;
String msg;
boolean isClientConnected;
InputStream input;
ObjectInputStream ois;
OutputStream output;
ObjectOutputStream oos; // ObjectOutputStream
public ServerThread(Socket s) {
threadSocket = s;
}
public void sendText(String text) {
try {
oos.writeObject(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
input = threadSocket.getInputStream();
ois = new ObjectInputStream(input);
output = threadSocket.getOutputStream();
oos = new ObjectOutputStream(output);
// get the user name from the client and store
// it inside thread class for later use
//msg = (String) ois.readObject();
isClientConnected = true;
//System.out.println(msg);
for(ServerThread t:allClients)
t.sendText("User has connected...");
// send this information to all users
// dos.writeUTF(userName + " has connected..");
// for(ServerThread t:allClients)
// t.sendText(msg);
while (isClientConnected) {
System.out.println("connect ... ");
try {
msg = (String) ois.readObject();
System.out.println(msg);
if (msg.equals("quit"))
break;
for (ServerThread t : allClients)
t.sendText(msg);
} catch (Exception e) {
}
}
// close all resources (streams and sockets)
ois.close();
oos.close();
threadSocket.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
this is the client (cl.java):
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
public class cl {
public static final String HOST = "127.0.0.1";
public static final int PORT = 6000;
static ConnectThread clientThread;
boolean isConnected;
static boolean isOnline = false;
static Scanner scanner = new Scanner(System.in);
static String msg;
public static void main(String[] args) {
new cl();
}
public cl() {
connectUser();
}
public void connectUser() {
clientThread = new ConnectThread();
clientThread.start();
}
class ConnectThread extends Thread {
InputStream input;
OutputStream output;
ObjectOutputStream oos;
Socket s;
public void sendText(String text) {
try {
System.out.println("sending text to server..");
oos.writeObject(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
s = new Socket(HOST, PORT);
output = s.getOutputStream();
oos = new ObjectOutputStream(output);
isOnline = true;
isConnected = true;
new ListenThread(s).start();
while (isOnline) {
System.out.println("Enter a Text to send:");
msg = scanner.nextLine();
clientThread.sendText("amjad: " + msg);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class ListenThread extends Thread {
Socket s;
InputStream input;
ObjectInputStream ois;
public ListenThread(Socket s) {
this.s = s;
try {
input = s.getInputStream();
ois = new ObjectInputStream(input);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
while (isConnected) {
try {
final String inputMessage = (String) ois.readObject();
System.out.println(inputMessage);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
thanks in advance
Im having a little problem i have managed to send info from client to server etc... but i want to be able to do it though telnet also (Open it up and say go telnet 127.0.0.1 4444, and then put in like 1 2 3 and then it comes up in the server just like it would if sending via the client. At the moment im getting this error:
java.io.StreamCorruptedException: invalid stream header: 310D0A32
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at ConnectionHandler.run(server1.java:73)
at java.lang.Thread.run(Unknown Source)
Let me know if i'm doing anything wrong please:
My main goal for this is to have it so i can enter say Username, ID and Name and then be able to recall them with a time, Like a very simple check in check out system. Would really love some help <3 :)
Client:
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class client1 {
public static void main(String[] args) {
try {
// Create a connection to the server socket on the server application
Socket socket = new Socket("localhost", 7777);
// Send a message to the client application
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
//oos.writeObject("A B C");
String data[]=new String[3];
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter details for the array");
for(int x=0;x<3;x++){
System.out.print("Enter word number"+(x+1)+":");
data[x]=br.readLine();
}
oos.writeObject(data);
System.out.println("Details sent to server...");
oos.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.ClassNotFoundException;
import java.lang.Runnable;
import java.lang.Thread;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class server1
{
private ServerSocket server;
private int port = 4444;
public server1()
{
try
{
server = new ServerSocket(port);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public static void main(String[] args)
{
server1 example = new server1();
example.handleConnection();
}
public void handleConnection()
{
System.out.println("Waiting for client message got...");
// The server do a loop here to accept all connection initiated by the
// client application.
while (true)
{
try
{
Socket socket = server.accept();
new ConnectionHandler(socket);
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable
{
private Socket socket;
public ConnectionHandler(Socket socket)
{
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run()
{
try
{
// Read a message sent by client application
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message[] = (String[]) ois.readObject();
//System.out.println("Message Received from client: " + message);
//b(message);
printArray(message);
ois.close();
socket.close();
System.out.println("Waiting for client message is...");
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
private void b(String message) {
List<String> list = new ArrayList<String>();
String[] arr = list.toArray(new String[0]);
System.out.println("Array is " + Arrays.toString(arr));
}
private void printArray(String[] arr){
for(String s:arr){
System.out.println(s);
}
}
I'm trying to send one object from the server side socket to the client side socket over TCP. I can't find out where is the problem.
Here is the error I'm getting on the Client side:
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2280)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2749)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:779)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:279)
at ClientSide.main(ClientSide.java:16)
Code for Server side:
import java.io.*;
import java.net.*;
import java.util.ArrayList;
public class ServerSide {
public static void main(String[] args) {
try
{
ServerSocket myServerSocket = new ServerSocket(9999);
Socket skt = myServerSocket.accept();
ArrayList<String> my = new ArrayList<String>();
my.set(0,"Bernard");
my.set(1, "Grey");
try
{
ObjectOutputStream objectOutput = new ObjectOutputStream(skt.getOutputStream());
objectOutput.writeObject(my);
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Code for the Client Side:
import java.io.*;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
public class ClientSide {
public static void main(String[] args)
{
try {
Socket socket = new Socket("10.1.1.2",9999);
ArrayList<String> titleList = new ArrayList<String>();
try {
ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream()); //Error Line!
try {
Object object = objectInput.readObject();
titleList = (ArrayList<String>) object;
System.out.println(titleList.get(1));
} catch (ClassNotFoundException e) {
System.out.println("The title list has not come from the server");
e.printStackTrace();
}
} catch (IOException e) {
System.out.println("The socket for reading the object has problem");
e.printStackTrace();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Changing from set to add does the trick
ArrayList<String> my = new ArrayList<String>();
my.add("Bernard");
my.add("Grey");
ps. as advised by the others this is not a good idea but, use only for learning