Based on this tutorial and another tutorial that unfortunately I can't get my hands on right now, I've created my Client-Server application but instead of sending string messages, the client asks for data(using Object Input/Output Streams) from the server using a custom class "Message".
First I created, the basic concept of it, using simple Java and tested both the server and the client on my computer, and displayed the data my client received in the console output. Everything worked out great, so I started to make the transition to Android(for the client). Trying to use the AsycTask, as show in the linked tutorial, I've managed so far to establish the connection between the client and the server. But I'm having a problem getting my server to read my "Message" object. Here are my classes:
Server:
import java.io.*;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class T_Server extends Thread {
private static int port = 4444;
private ServerSocket srvSock = null;
private Socket clntSock = null;
private boolean running = false;
private ObjectInputStream in;
private ObjectOutputStream out;
private OnMessageReceived msgListener;
private Message msgIn;
private Object objSend;
public static void main(String[] args) {
OnMessageReceived _msgListener=new OnMessageReceived();
T_Server server=new T_Server(_msgListener);
server.start();
}
public T_Server(OnMessageReceived _msgListener) {
this.msgListener = _msgListener;
}
public void send(Object _msg) {
if (out != null) {
try {
out.writeObject(_msg);
out.flush();
} catch (IOException ex) {
Logger.getLogger(T_Server.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
#Override
public void run() {
running = true;
try {
srvSock = new ServerSocket(port);
System.out.println("Server startet. IP : " + InetAddress.getLocalHost() + ", Port : " + srvSock.getLocalPort());
System.out.println("\nWaiting for a client ...");
clntSock = srvSock.accept();
System.out.println("\nClient accepted: " + clntSock);
try {
out = new ObjectOutputStream(clntSock.getOutputStream());
in = new ObjectInputStream(clntSock.getInputStream());
while (running) {
msgIn = (Message) in.readObject();
System.out.println(msgIn.toString());
objSend = msgListener.messageReceived(msgIn);
send(objSend);
}
} catch (Exception e) {
System.out.println("S: Error");
e.printStackTrace();
} finally {
clntSock.close();
}
} catch (Exception e) {
System.out.println("S: Error");
e.printStackTrace();
}
}
}
I use the same Message class both on the Server and on the Client
Message Class:
import java.io.Serializable;
public class Message implements Serializable{
private static final long serialVersionUID = 1L;
public String sender, content, type;
public Message(String sender, String type, String content){
this.sender = sender; this.type=type; this.content = content;
}
#Override
public String toString(){
return "{type='"+type+"', sender='"+sender+"', content='"+content+"'}";
}
}
I have also created a class to handle the Messages, on the server side, called OnMessageReceived.
P.S. In this class there are fields and some options that have to do with my backend database.
OnMessageReceived:
import java.sql.SQLException;
import java.util.regex.Pattern;
public class OnMessageReceived {
public Object messageReceived(Message message) throws SQLException {
Message _msg = message;
Database db = new Database();
Object objReturn;
String strResult;
boolean addResult;
final Pattern pattern = Pattern.compile("\\[.*?&");
final String[] result;
if (_msg.type.equals("getUsers")) {
objReturn = db.getUsers();
return objReturn;
} else if (_msg.type.equals("getFriends")) {
objReturn = db.getFriends(_msg.sender);
return objReturn;
} else if (_msg.type.equals("addFriend")) {
String _UserName, _UserNameFriend;
_UserName = _msg.sender;
_UserNameFriend = _msg.content;
addResult = db.addFriend(_UserName, _UserNameFriend);
if (addResult) {
strResult = "Add was successfull";
return strResult;
} else if (!addResult) {
strResult = "Add failed";
return strResult;
}
System.out.println(addResult);
} else if (_msg.type.equals("addUser")) {
String _UserName, _Password, _Phone;
result = pattern.split(_msg.content);
_UserName = _msg.sender;
_Password = result[0];
_Phone = result[1];
addResult = db.addUser(_UserName, _Password, _Phone);
if (addResult) {
strResult = "Add was successfull";
return strResult;
} else if (!addResult) {
strResult = "Add failed";
return strResult;
}
System.out.println(addResult);
} else if (_msg.type.equals("Login")) {
boolean isUser;
String _UserName;
_UserName = _msg.sender;
isUser = db.isUser(_UserName);
if (isUser) {
strResult = "Login Successfull";
return strResult;
} else if (!isUser) {
strResult = "Login failed";
return strResult;
}
}
return null;
}
}
For the client side(on the Android) it's very simillar to the one in the linked tutorial.
The difference is that I only have 2 buttons, one to connect to the server and one to send my message, which is an instance of my Message class.
Client:
import java.io.*;
import java.net.*;
import android.util.Log;
public class T_Client {
private static final String TAG = "MyActivity";
private static String serverIP = "192.168.1.11";
private static int port = 4444;
private InetAddress serverAddr = null;
private Socket sock = null;
private boolean running = false;
private ObjectInputStream in;
private ObjectOutputStream out;
private OnMessageReceived msgListener;
Object objIn, objReceived;
public T_Client(OnMessageReceived _msgListener){
this.msgListener=_msgListener;
}
public void send(Message _msg) {
if (out != null) {
try {
out.writeObject(_msg);
out.flush();
Log.i(TAG,"Outgoing : " + _msg.toString());
} catch (IOException ex) {
Log.e(TAG,ex.toString());
}
}
}
public void stopClient(){
running = false;
}
public void run(){
running = true;
try {
//here you must put your computer's IP address.
serverAddr = InetAddress.getByName(serverIP);
Log.i("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
sock = new Socket(serverAddr, port);
try {
//send the message to the server
out =new ObjectOutputStream(sock.getOutputStream());
//receive the message which the server sends back
in =new ObjectInputStream(sock.getInputStream());
Log.i("TCP Client", "C: Connected.");
//in this while the client listens for the messages sent by the server
while (running) {
objIn = in.readObject();
if (objIn != null && msgListener != null) {
//call the method messageReceived from MyActivity class
msgListener.messageReceived(objIn);
}
objIn = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + objIn + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
sock.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
public interface OnMessageReceived {
public void messageReceived(Object objReceived);
}
}
Main Activity:
import java.io.IOException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
private static final String TAG = "MyActivity";
private T_Client client;
private Message msgSend;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void connect(View v) throws IOException {
new connectTask().execute("");
}
public void btnSend(View v) throws IOException {
msgSend=new Message("Setlios", "getUsers", "");
if(client!=null){
client.send(msgSend);
}
}
public class connectTask extends AsyncTask<Object,Object,T_Client> {
#Override
protected T_Client doInBackground(Object... objIn) {
//we create a TCPClient object and
client = new T_Client(new T_Client.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(Object objIn) {
//this method calls the onProgressUpdate
publishProgress(objIn);
}
});
client.run();
return null;
}
#Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
Log.i(TAG,values.getClass().getName().toString());
}
}
}
When I hit the "Send" button I get this error on the server console which points me to the point where I read the object read from the ObjectInputStream and pass it an instance of the Message class but I can't understand what the problem is. I also noticed that it shows this "in.neverhide.connect" which is the package name of the project for my android client
java.lang.ClassNotFoundException: in.neverhide.connect.Message
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:622)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1593)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)
at Objects_WORKING.T_Server.run(T_Server.java:61)
Ok after searching around I found this post and the answer from Akinsola 'mys Tunmise. I've made the Message class into a jar and used it as an external reference in both the client and the server.
Related
I write my own Java FTP server. Until recently I used PUttY to debug my control telnet connection and everything seemed fine - I had successful two-way communication. Now I try to debug my server with FileZilla, but it does not seem to read my text, nor to send some to server, so it just hangs and wait for something.
Control connection class
public class ControlConnection extends Thread {
private enum OperationMode {
ACTIVE, PASSIVE
}
private final Map<String, Supplier<String>> COMMANDS;
private String[] userTokens;
private User user;
private String userLogin;
private boolean authenticated;
private boolean dataConnected;
private boolean userExists;
private final Socket socket;
private DataInputStream inputStream;
private DataOutputStream outputStream;
private DataConnection ftpSession;
private OperationMode operationMode;
private String errorMessage;
public ControlConnection(Socket socket) {
super(ControlConnection.class.toString());
this.socket = socket;
// constants initialization
authenticated = false;
dataConnected = false;
// commands initialization
COMMANDS = new HashMap<>();
// commands init
}
#Override
public void run() {
try {
inputStream = new DataInputStream(socket.getInputStream());
outputStream = new DataOutputStream(socket.getOutputStream());
sendGreetings();
IOProcessing.writeBytes(outputStream, pasvCommand());;
boolean running = true;
while (running) {
sendGreetings();
String input = IOProcessing.readBytes(inputStream);
if (!(input.equals("")))
System.out.println(input);
if (!checkInput(input))
continue;
userTokens = input.split(" ");
String command = userTokens[0].toUpperCase();
String answer = COMMANDS.get(command).get();
outputStream.writeBytes(answer);
}
}
catch (IOException e) {
System.err.println(e);
System.exit(-1);
}
}
private boolean commonCheck() {
// some checks
return true;
}
private String getErrorMessage() {
return errorMessage;
}
public void sendGreetings() {
String greetings = String.format("220 Control connection established: %s", getConnectionInfo());
IOProcessing.writeBytes(outputStream, greetings);
}
public String getConnectionInfo() {
String info = String.format("%s: %d %s",
socket.getInetAddress().toString(), socket.getPort(), user != null ? user.getUsername(): "");
return info;
}
// input/output proccessing functions
public boolean checkInput(String input) {
// checks
return true;
}
// commands functions
private String pasvCommand() {
if (operationMode == OperationMode.PASSIVE) {
errorMessage = "Already in passive mode.%n";
return errorMessage;
}
String answer;
new ListenToSocket().start();
answer = String.format("227 Entering Passive Mode (%s, %d)",
"127.0.0.1", DataConnection.PORT);
operationMode = OperationMode.PASSIVE;
return answer;
}
private class ListenToSocket extends Thread {
public ListenToSocket() {
}
#Override
public void run() {
try {
ServerSocket ftpSocket =
new ServerSocket(DataConnection.PORT);
ftpSession =
DataConnection.getDataConnection(ftpSocket.accept());
if (ftpSession != null) {
ftpSession.start();
dataConnected = true;
String greetings = "Data connection established: " + ftpSession.getConnectionInfo();
IOProcessing.writeBytes(outputStream, greetings);
} else {
dataConnected = false;
}
} catch (IOException e) {
System.out.print(e);
}
}
}
also, server does not get user credentials, entered in FileZilla - input from server is always empty
IOProcessing class
public class IOProcessing {
private static final Charset UTF8_CHARSET;
static {
UTF8_CHARSET = Charset.forName("UTF-8");
}
public static String readBytes(DataInputStream inputStream) {
String result = "";
try {
int len = inputStream.available();
if (len == 0) {
return result;
}
byte[] byteInput = new byte[len];
inputStream.readFully(byteInput, 0, len);
result = new String(byteInput, "UTF-8").trim();
} catch (IOException e) {
System.err.println(e);
}
return result;
}
output FileZlla log
Status: Resolving address of localhost
Status: Connecting to [::1]:21...
Status: Connection established, waiting for welcome message.
You didn't show us the writeBytes. So I can only guess that you are not sending \r\n after the messages sent to the client. Particularly after the welcome message. So FileZilla keeps waiting forever for it, as any FTP client would do.
I am trying to develop some kind of chat application (learning purposes) but when I send my objects from the client to the server only the first one seems to get received. No error is shown or nothing so I don't really know whats wrong.
Server code:
import chattychat.domain.Message;
import chattychat.domain.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
*
* #author
*/
public class Server {
private final int PORT;
private ServerSocket server;
public Server(){
this.PORT = 6565;
}
public Server(int port){
this.PORT = port;
}
public void listenSocket(){
try{
this.server = new ServerSocket(this.PORT);
} catch (IOException e) {
System.out.println("Could not listen on port 4444");
System.exit(-1);
}
while(true){
ClientWorker w;
try{
//server.accept returns a client connection
w = new ClientWorker(server.accept());
Thread t = new Thread(w);
t.start();
} catch (IOException e) {
System.out.println("Accept failed: 4444");
}
}
}
class ClientWorker implements Runnable {
private Socket client;
private ObjectInputStream in;
//Constructor
ClientWorker(Socket client) {
this.client = client;
}
public void run(){
try{
this.in = new ObjectInputStream(this.client.getInputStream());
Object obj = this.in.readObject();
System.out.println("called");
if(obj instanceof Message){
Message msg = (Message)obj;
System.out.println(msg);
}else if(obj instanceof User){
User user = (User)obj;
System.out.println(user);
}
System.out.println();
}catch (IOException e) {
System.out.println("Read failed");
//System.exit(-1);
} catch (ClassNotFoundException ex) {
System.out.println("Object not found");
//System.exit(-1);
}
}
}
#Override
protected void finalize(){
try{
this.server.close();
} catch (IOException e) {
System.out.println("Could not close socket");
System.exit(-1);
}
}
public static void main(String[] args){
Server s = new Server();
//s.communicate();
s.listenSocket();
}
}
Client code:
import chattychat.domain.Message;
import chattychat.domain.User;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.SocketException;
/**
*
* #author laurensputseys
*/
public class Client {
private final int PORT = 6565;
private String SERVER = "localhost";
private Socket socket;
private ObjectInputStream in;
private ObjectOutputStream out;
private boolean isConnected;
public Client(){
this.isConnected = false;
}
public Client(String server){
this.SERVER = server;
}
public String getServer(){
return this.SERVER;
}
public int getPort(){
return this.PORT;
}
public void communicate(Message msg){
while(!isConnected){
try{
this.socket = new Socket(this.getServer(), this.getPort());
isConnected = true;
this.out = new ObjectOutputStream(this.socket.getOutputStream());
this.out.writeObject(msg);
this.out.flush();
this.out.close();
}catch(SocketException se){
se.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
public void register(User usr){
while(!isConnected){
try{
this.socket = new Socket(this.getServer(), this.getPort());
isConnected = true;
this.out = new ObjectOutputStream(this.socket.getOutputStream());
this.out.writeObject(usr);
this.out.flush();
this.out.close();
}catch(SocketException se){
se.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}
}
}
public boolean isConnected(){
return isConnected;
}
public static void main(String[] args){
Client c = new Client();
User u1 = new User("firstname 1", "lastname1", "testuser");
User u2 = new User("firstname 2", "lastname2", "Testuser");
Message m1 = new Message(u1, u2, "Hello from P1 to P2");
Message m2 = new Message(u2, u1, "Hello from P2 to P1");
System.out.println("Send 1");
c.communicate(m1);
System.out.println("Send 2");
c.communicate(m2);
System.out.println("Send 3");
c.register(u1);
}
}
message class:
import java.io.Serializable;
import java.util.Objects;
/**
*
* #author
*/
public class Message implements Serializable{
private static final long serialVersionUID = 7526472295622776147L;
private User from;
private User to;
private String message;
public Message(User from, User to, String message){
this.setFrom(from);
this.setTo(to);
this.setMessage(message);
}
private void setFrom(User from){
this.from = from;
}
private void setTo(User to){
this.to = to;
}
private void setMessage(String message){
this.message = message;
}
public String getMessage(){
return this.message;
}
#Override
public boolean equals(Object o){
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
Message tmpMsg = (Message)o;
return this.to.equals(tmpMsg.to) && this.from.equals(tmpMsg.from) && this.getMessage().equals(tmpMsg.getMessage());
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + Objects.hashCode(this.from);
hash = 59 * hash + Objects.hashCode(this.to);
hash = 59 * hash + Objects.hashCode(this.message);
return hash;
}
#Override
public String toString(){
return "From: " + this.from + " to: " + this.to + " message: " +this.getMessage();
}
}
User class:
import java.io.Serializable;
import java.util.Objects;
/**
*
* #author
*/
public class User implements Serializable{
private static final long serialVersionUID = 7526456787322776147L;
private String firstname;
private String lastname;
private String password;
public User(String firstname, String lastname, String password){
setFirstname(firstname);
setLastname(lastname);
setPassword(password);
}
private void setFirstname(String firstname){
this.firstname = firstname; //TODO
}
private void setLastname(String lastname){
this.lastname = lastname; //TODO
}
private void setPassword(String password){
this.password = password; //TODO
}
#Override
public boolean equals(Object o){
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
User tmpUser = (User)o;
return this.firstname.equals(tmpUser.firstname) && this.lastname.equals(tmpUser.lastname);
}
#Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + this.firstname.length();
hash = 59 * hash + this.lastname.length();
hash = 59 * hash + this.password.length();
return hash;
}
#Override
public String toString(){
return this.firstname + " " + this.lastname;
}
}
Thanks in advance!
Without reading your code very thoroughly. Your clients communicate methods sets connected to true on the first call. So the while loop will not be entered on the second call to communicate. You should separate connecting to server and sending messages. Also, your client worker thread in server seems to return after one object read. The run method should return when connection is broken, not when one message is read.
I am new to J2ME and am building a mobile application where users can register, login and be presented with some member only screen where they can perform some operations.
(I am into web development, hence kindly correct me where I use a web approach. Also, I clearly understand basic java concepts but have not built a mobile app before)
So far, I have created the first screen with a login form containing a username and password textbox, and Login and Exit buttons.
The problems I am currently facing are:
How can I provide access to Register, Login and Exit at the same time (it seems the phone can only have two buttons at a time). Do I provide them as command buttons or normal 'web like buttons that appear on page'? Kindly tell me how for any of the options that seems appropriate.
How do I send and receive data over http in the mobile application? Sample code will be appreciated.
How do I manage the different screens? In web development, I simply create pages and link them up. In this case, how can I display a register screen when the register button is pressed? The home screen when login is successful? or an error message when unsuccessful?
Do I have different functions that dynamically generates the screens? and I call them each time when the screens are requested?
Simple samples will be highly appreciated.
In J2ME,
You have the display object which determines what is shown on the screen. There are something which can be displayed. For example a Form, List, Textbox etc. Therefore what you can do is you can create the following displays
public class IndexScreen extends List implements CommandListener {
//This will contain the options
//1. Register
//2. Login
//3. Exit
}
public class RegsterScreen extends Form implements CommandListener {
//This will contain register fields and submit cancel command buttons
}
public class LoginScreen extends Form implements CommandListener {
//This will contain Login specific controls
}
Now once these displayable objects are ready you can keep changing the display on some events like click of a command button.
public void commandAction(Command c, Displayable d) {
if (c == OK) {
nextScreen = new RegisterScreen();
display.setCurrent(nextScreen);
}
if (c == BACK) {
display.setCurrent(prevScreen);
}
For sending and receiving data the following may help....
package madmin.client;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.lcdui.Display;
import madmin.res.Globals;
public class ClientRequest {
private Client client;
private Display display;
private String requestServlet;
private String requestCode;
private String requestId;
private String userId;
private String url;
private String response;
private String parameterOne;
public ClientRequest() {
}
public boolean sendRequest() {
boolean result = false;
userId = Globals.getUserId();
url = Globals.getURL() + requestServlet + "?requestCode=" + requestCode + "&requestId=" + requestId + "&userId=" + userId + "&clientIP=" + client.getIpAddress() + "&clientHostName=" + client.getHostname() + "¶meterOne=" + parameterOne;
System.out.println("User Id value in ClientRequest " + userId);
System.out.println("Start HTTP Connection");
HttpConnection connection = null;
InputStream inputstream = null;
try {
connection = (HttpConnection) Connector.open(url);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("Content-Type", "//text plain");
connection.setRequestProperty("Connection", "close");
System.out.println("Status Line COde: "+ connection.getResponseCode());
System.out.println("Status Line Message: "+ connection.getResponseMessage());
if(connection.getResponseCode()==HttpConnection.HTTP_OK){
inputstream = connection.openInputStream();
int length = (int) connection.getLength();
if(length!=-1){
byte incomingData[] = new byte[length];
inputstream.read(incomingData);
response = new String(incomingData);
}
else {
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
while((ch = inputstream.read())!=-1){
bytestream.write(ch);
}
response = new String(bytestream.toByteArray());
bytestream.close();
}
System.out.println("Response:" + response.trim());
if(response.trim().equals("Request Submitted Successfully")){
result = true;
}
else{
result = false;
}
}
connection.close();
if(inputstream!=null)inputstream.close();
}
catch(Exception e) {
e.printStackTrace();
}
finally {
if(inputstream!=null){
try{
inputstream.close();
}
catch(Exception e){
e.printStackTrace();
}
}
}
return result;
}
public Client getClient() {
return client;
}
public void setClient(Client client) {
this.client = client;
}
public Display getDisplay() {
return display;
}
public void setDisplay(Display display) {
this.display = display;
}
public String getRequestCode() {
return requestCode;
}
public void setRequestCode(String requestCode) {
this.requestCode = requestCode;
}
public String getRequestId() {
return requestId;
}
public void setRequestId(String requestId) {
this.requestId = requestId;
}
public String getRequestServlet() {
return requestServlet;
}
public void setRequestServlet(String requestServlet) {
this.requestServlet = requestServlet;
}
public String getResponse() {
return response;
}
public void setResponse(String response) {
this.response = response;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getParameterOne() {
return parameterOne;
}
public void setParameterOne(String parameterOne) {
this.parameterOne = parameterOne;
}
}
and....
package madmin.client;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import madmin.res.Globals;
public class ClientResponse {
private String response;
public String getResponse(String requestId) {
System.out.println("Start HTTP Connection");
HttpConnection connection = null;
InputStream inputstream = null;
response = "";
try{
connection = (HttpConnection) Connector.open( Globals.getURL() + "ResponseServlet?requestId=" + requestId);
connection.setRequestMethod(HttpConnection.GET);
connection.setRequestProperty("Content-Type", "//text plain");
connection.setRequestProperty("Connection", "close");
System.out.println("Status Line COde: "+ connection.getResponseCode());
System.out.println("Status Line Message: "+ connection.getResponseMessage());
if(connection.getResponseCode()==HttpConnection.HTTP_OK){
inputstream = connection.openInputStream();
int length = (int) connection.getLength();
if(length!=-1){
byte incomingData[] = new byte[length];
inputstream.read(incomingData);
response = new String(incomingData);
}
else {
ByteArrayOutputStream bytestream = new ByteArrayOutputStream();
int ch;
while((ch = inputstream.read())!=-1){
bytestream.write(ch);
}
response = new String(bytestream.toByteArray());
bytestream.close();
}
System.out.println("Response:" + response.trim());
connection.close();
if(inputstream!=null)inputstream.close();
}
}
catch(Exception e){
e.printStackTrace();
}
return response;
}
}
edited:
something like this
public class MenuScreen extends List implements CommandListener{
public MenuScreen() {
append("Register", null);
append("Login", null);
append("Forgot password", null);
select = new Command("Select", Command.OK, 1);
addCommand(select);
setCommandListener(this);
}
}
public void commandAction(Command command, Displayable display) {
if(command==List.SELECT_COMMAND){
String menuItem = this.getString(menuIndex);
}
if(command==select){
if( menuItem.equals("Register"))
display.setCurrent(new RegisterScreen())
}
}
This is one of the most common application scenario that can be found all over the net. and I'm not asking any questions about the java codes that I did because I was successful in running it on my laptop where both the client and server part of the .java file resides. Rather I have had problem getting it to work in between two computers. I tried establishing physical connection using cross-over cable to connect two computers, and did a test to see if file transfers successfully and it did, however, keeping one Server part of the .java file in one computer and client part in the other, I tried to run the server first and then the client but it got a "access denied" error.
For reference here's my two .java files:
/* ChatClient.java */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ChatClient {
private static int port = 5000; /* port to connect to */
private static String host = "localhost"; /* host to connect to (server's IP)*/
private static BufferedReader stdIn;
private static String nick;
/**
* Read in a nickname from stdin and attempt to authenticate with the
* server by sending a NICK command to #out. If the response from #in
* is not equal to "OK" go bacl and read a nickname again
*/
private static String getNick(BufferedReader in,
PrintWriter out) throws IOException {
System.out.print("Enter your nick: ");
String msg = stdIn.readLine();
out.println("NICK " + msg);
String serverResponse = in.readLine();
if ("SERVER: OK".equals(serverResponse)) return msg;
System.out.println(serverResponse);
return getNick(in, out);
}
public static void main (String[] args) throws IOException {
Socket server = null;
try {
server = new Socket(host, port);
} catch (UnknownHostException e) {
System.err.println(e);
System.exit(1);
}
stdIn = new BufferedReader(new InputStreamReader(System.in));
/* obtain an output stream to the server... */
PrintWriter out = new PrintWriter(server.getOutputStream(), true);
/* ... and an input stream */
BufferedReader in = new BufferedReader(new InputStreamReader(
server.getInputStream()));
nick = getNick(in, out);
/* create a thread to asyncronously read messages from the server */
ServerConn sc = new ServerConn(server);
Thread t = new Thread(sc);
t.start();
String msg;
/* loop reading messages from stdin and sending them to the server */
while ((msg = stdIn.readLine()) != null) {
out.println(msg);
}
}
}
class ServerConn implements Runnable {
private BufferedReader in = null;
public ServerConn(Socket server) throws IOException {
/* obtain an input stream from the server */
in = new BufferedReader(new InputStreamReader(
server.getInputStream()));
}
public void run() {
String msg;
try {
/* loop reading messages from the server and show them
* on stdout */
while ((msg = in.readLine()) != null) {
System.out.println(msg);
}
} catch (IOException e) {
System.err.println(e);
}
}
}
and here's the ChatServer.java:
/* ChatServer.java */
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Hashtable;
public class ChatServer {
private static int port = 5000; /* port to listen on */
public static void main (String[] args) throws IOException
{
ServerSocket server = null;
try {
server = new ServerSocket(port); /* start listening on the port */
} catch (IOException e) {
System.err.println("Could not listen on port: " + port);
System.err.println(e);
System.exit(1);
}
Socket client = null;
while(true) {
try {
client = server.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.err.println(e);
System.exit(1);
}
/* start a new thread to handle this client */
Thread t = new Thread(new ClientConn(client));
t.start();
}
}
}
class ChatServerProtocol {
private String nick;
private ClientConn conn;
/* a hash table from user nicks to the corresponding connections */
private static Hashtable<String, ClientConn> nicks =
new Hashtable<String, ClientConn>();
private static final String msg_OK = "OK";
private static final String msg_NICK_IN_USE = "NICK IN USE";
private static final String msg_SPECIFY_NICK = "SPECIFY NICK";
private static final String msg_INVALID = "INVALID COMMAND";
private static final String msg_SEND_FAILED = "FAILED TO SEND";
/**
* Adds a nick to the hash table
* returns false if the nick is already in the table, true otherwise
*/
private static boolean add_nick(String nick, ClientConn c) {
if (nicks.containsKey(nick)) {
return false;
} else {
nicks.put(nick, c);
return true;
}
}
public ChatServerProtocol(ClientConn c) {
nick = null;
conn = c;
}
private void log(String msg) {
System.err.println(msg);
}
public boolean isAuthenticated() {
return ! (nick == null);
}
/**
* Implements the authentication protocol.
* This consists of checking that the message starts with the NICK command
* and that the nick following it is not already in use.
* returns:
* msg_OK if authenticated
* msg_NICK_IN_USE if the specified nick is already in use
* msg_SPECIFY_NICK if the message does not start with the NICK command
*/
private String authenticate(String msg) {
if(msg.startsWith("NICK")) {
String tryNick = msg.substring(5);
if(add_nick(tryNick, this.conn)) {
log("Nick " + tryNick + " joined.");
this.nick = tryNick;
return msg_OK;
} else {
return msg_NICK_IN_USE;
}
} else {
return msg_SPECIFY_NICK;
}
}
/**
* Send a message to another user.
* #recepient contains the recepient's nick
* #msg contains the message to send
* return true if the nick is registered in the hash, false otherwise
*/
private boolean sendMsg(String recipient, String msg) {
if (nicks.containsKey(recipient)) {
ClientConn c = nicks.get(recipient);
c.sendMsg(nick + ": " + msg);
return true;
} else {
return false;
}
}
/**
* Process a message coming from the client
*/
public String process(String msg) {
if (!isAuthenticated())
return authenticate(msg);
String[] msg_parts = msg.split(" ", 3);
String msg_type = msg_parts[0];
if(msg_type.equals("MSG")) {
if(msg_parts.length < 3) return msg_INVALID;
if(sendMsg(msg_parts[1], msg_parts[2])) return msg_OK;
else return msg_SEND_FAILED;
} else {
return msg_INVALID;
}
}
}
class ClientConn implements Runnable {
private Socket client;
private BufferedReader in = null;
private PrintWriter out = null;
ClientConn(Socket client) {
this.client = client;
try {
/* obtain an input stream to this client ... */
in = new BufferedReader(new InputStreamReader(
client.getInputStream()));
/* ... and an output stream to the same client */
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.err.println(e);
return;
}
}
public void run() {
String msg, response;
ChatServerProtocol protocol = new ChatServerProtocol(this);
try {
/* loop reading lines from the client which are processed
* according to our protocol and the resulting response is
* sent back to the client */
while ((msg = in.readLine()) != null) {
response = protocol.process(msg);
out.println("SERVER: " + response);
}
} catch (IOException e) {
System.err.println(e);
}
}
public void sendMsg(String msg) {
out.println(msg);
}
}
Now, what should I do in order to run this two files from two computers given that I have the physical connection(TCP/IP) setup already??
Thanks in advance... :)
Sounds like it's quite possibly a firewall problem. Have you tried opening a hole in your firewall for port 1001?
Have you also looked at your java.policy and make sure that it is configured to allow local codebase to open sockets?
as mentioned in comment, you should not use port < 1025 for you applications, since they are always used in deamon processes. However you should test your program like this
1) if you get connection refused then you should check the exception properly, whether client program takes time before generating exception ( that mean request is going to server and then it's giving connection refused), in that case you should try java.policy put following in a file named java.policy
grant {
permission java.net.SocketPermission ":1024-65535",
"connect,accept";
permission java.net.SocketPermission ":80", "connect";
permission java.io.FilePermission "", "read,write,delete";
permission java.security.SecurityPermission "";
};
while compiling use this flag -Djava.security.policy=java.policy
more-over you should also try -Djava.rmi.server.hostname=IP, where IP is clien-ip for client.java and server-ip for server.java
2) if you are immediately getting exception at client side then your request is not going outside your pc, so client has some problem.
check the exception properly and post them over here.
3) though i've not got access denied error, but it seems to have port problem that might be solved using policy or port>1024.
post what are you getting now.
I am really not clear on explaining this requirement but what I need basically is a JSP page that connects to a Unix server and gets the word count of a file and displays on the JSP page. I have looked on various questions here but nothing helped. A sample code would be of much help. Thanks
Kavin, I guess you must have found some other solution or moved on by now. However, I just came across a requirement that led me to this page.
I looked through the somewhat smuckish responses on this page and many others but could not find a simple to use Telnet client at all.
I spent a little bit of time and wrote a simple client on top of Commons Net's solution. Please forgive the System.out and System.err in the code, I got it to barely work.
public static void main(String[] args) throws Exception {
SimpleTelnetClient client = new SimpleTelnetClient("localhost", 2323);
client.connect();
String result = client.waitFor("login:");
System.out.println("Got " + result);
client.send("username");
result = client.waitFor("Password:");
System.out.println("Got " + result);
client.send("password");
client.waitFor("#");
client.send("ls -al");
result = client.waitFor("#");
System.out.println("Got " + result);
client.send("exit");
}
Not sure if it will help you anymore, but perhaps it could be a starting point for others.
import java.io.InputStream;
import java.io.PrintStream;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import org.apache.commons.net.telnet.EchoOptionHandler;
import org.apache.commons.net.telnet.InvalidTelnetOptionException;
import org.apache.commons.net.telnet.SuppressGAOptionHandler;
import org.apache.commons.net.telnet.TelnetClient;
import org.apache.commons.net.telnet.TerminalTypeOptionHandler;
public class SimpleTelnetClient {
static class Responder extends Thread {
private StringBuilder builder = new StringBuilder();
private final SimpleTelnetClient checker;
private CountDownLatch latch;
private String waitFor = null;
private boolean isKeepRunning = true;
Responder(SimpleTelnetClient checker) {
this.checker = checker;
}
boolean foundWaitFor(String waitFor) {
return builder.toString().contains(waitFor);
}
public synchronized String getAndClearBuffer() {
String result = builder.toString();
builder = new StringBuilder();
return result;
}
#Override
public void run() {
while (isKeepRunning) {
String s;
try {
s = checker.messageQueue.take();
} catch (InterruptedException e) {
break;
}
synchronized (Responder.class) {
builder.append(s);
}
if (waitFor != null && latch != null && foundWaitFor(waitFor)) {
latch.countDown();
}
}
}
public String waitFor(String waitFor) {
synchronized (Responder.class) {
if (foundWaitFor(waitFor)) {
return getAndClearBuffer();
}
}
this.waitFor = waitFor;
latch = new CountDownLatch(1);
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
String result = null;
synchronized (Responder.class) {
result = builder.toString();
builder = new StringBuilder();
}
return result;
}
}
static class TelnetReader extends Thread {
private final SimpleTelnetClient checker;
private final TelnetClient tc;
TelnetReader(SimpleTelnetClient checker, TelnetClient tc) {
this.checker = checker;
this.tc = tc;
}
#Override
public void run() {
InputStream instr = tc.getInputStream();
try {
byte[] buff = new byte[1024];
int ret_read = 0;
do {
ret_read = instr.read(buff);
if (ret_read > 0) {
checker.sendForResponse(new String(buff, 0, ret_read));
}
} while (ret_read >= 0);
} catch (Exception e) {
System.err.println("Exception while reading socket:" + e.getMessage());
}
try {
tc.disconnect();
checker.stop();
System.out.println("Disconnected.");
} catch (Exception e) {
System.err.println("Exception while closing telnet:" + e.getMessage());
}
}
}
private String host;
private BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();
private int port;
private TelnetReader reader;
private Responder responder;
private TelnetClient tc;
public SimpleTelnetClient(String host, int port) {
this.host = host;
this.port = port;
}
protected void stop() {
responder.isKeepRunning = false;
responder.interrupt();
}
public void send(String command) {
PrintStream ps = new PrintStream(tc.getOutputStream());
ps.println(command);
ps.flush();
}
public void sendForResponse(String s) {
messageQueue.add(s);
}
public void connect() throws Exception {
tc = new TelnetClient();
TerminalTypeOptionHandler ttopt = new TerminalTypeOptionHandler("VT100", false, false, true, false);
EchoOptionHandler echoopt = new EchoOptionHandler(true, false, true, false);
SuppressGAOptionHandler gaopt = new SuppressGAOptionHandler(true, true, true, true);
try {
tc.addOptionHandler(ttopt);
tc.addOptionHandler(echoopt);
tc.addOptionHandler(gaopt);
} catch (InvalidTelnetOptionException e) {
System.err.println("Error registering option handlers: " + e.getMessage());
}
tc.connect(host, port);
reader = new TelnetReader(this, tc);
reader.start();
responder = new Responder(this);
responder.start();
}
public String waitFor(String s) {
return responder.waitFor(s);
}
}
Why wouldn't you just use an open source telnet client. There is bound to be several to choose from. Google lists many.