I'm new to network I/O programming, and I've run into a snag-- basically what I want to do is have a desktop app talk to the google maps javascript API. In order to facilitate this, I have built a java applet which will act as a bridge between the desktop app and the browser javascript app. When I run the desktop app and applet together in Eclipse they can communicate perfectly, and I am able to invoke applet functions by writing strings to a Socket bound to the same port the applet has established a ServerSocket connection with. For testing purposes in Eclipse, I send the string "sendJSAlertTest" to the socket's outputstream, then derive a Method instance using the java.lang.reflect API from the ServerSocket inputstream, and then finally invoke the resulting method in the applet. When the applet is running in a browser I write "sendJSAlert" to the socket instead since it leads to the actual invocation of javascript. The result in Eclipse using the appletviewer is that the desktop application context prints the output "awesome sendJSAlert" and the applet context prints the output from the sendJSAlertTest() method, "Hello Client, I'm a Server!". The result of passing "sendJSAlert" to the applet running in the browser is that the desktop application prints null, suggesting that for some reason the inputstream of the ServerSocket is empty, and the browser itself does nothing when it should generate a javascript alert box with the text "Hello Client, I'm a Server!". The browser I'm using is Google Chrome, and for the moment I am simply running everything on the local machine (e.g. no remote server involved yet)
Below is the relevant Java code and HTML:
SocketClient.java
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class SocketClient {
Socket socket = null;
PrintWriter out = null;
BufferedReader in = null;
private InetAddress myAddress;
private String remoteFunction;
public SocketClient(){
}
public void listenSocket(int portNum){
//Create socket connection
try{
System.out.println("#Client Trying to create socket bound to port " + portNum);
socket = new Socket(<my hostname here as a string>, portNum);
System.out.println("the attached socket port is " + socket.getLocalPort());
System.out.flush();
out = new PrintWriter(socket.getOutputStream(), true);
out.println("sendJSAlertTest");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = in.readLine();
System.out.println("#CLient side Text received from server: " + line);
} catch (UnknownHostException e) {
System.out.println("Unknown host: <my hostname here as a string>.eng");
System.exit(1);
} catch (IOException e) {
System.out.println("No I/O");
e.printStackTrace();
System.exit(1);
}
}
public void setRemoteFunction(String funcName){
remoteFunction = funcName;
}
public String getRemoteFunction(){
return remoteFunction;
}
}
SocketServer.java
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.*;
class SocketServer {
ServerSocket server = null;
Socket client = null;
BufferedReader in = null;
PrintWriter out = null;
String line;
private NetComm hNet;
private Method serverMethod;
SocketServer(NetComm netmain){
hNet = netmain;
}
public void listenSocket(int portNum){
try{
System.out.println("#server Trying to create socket bound to port " + portNum);
server = new ServerSocket(portNum);
System.out.println("the attached socket port is " + server.getLocalPort());
} catch (IOException e) {
System.out.println("Could not listen on port " + portNum);
System.exit(-1);
}
try{
client = server.accept();
System.out.println("Connection accepted!");
} catch (IOException e) {
System.out.println("Accept failed: " + portNum);
System.exit(-1);
}
try{
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Accept failed: " + portNum);
System.exit(-1);
}
while(true){
try{
System.out.println("trying to read from inputstream...");
line = in.readLine();
System.out.println(line);
//Now that we have a method name, invoke it
try {
serverMethod = hNet.getClass().getDeclaredMethod(line,
String.class);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
serverMethod.invoke(hNet, "Hello Client, I'm a Server!");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Send data back to client
out.println("awesome " + line);
} catch (IOException e) {
System.out.println("Read failed");
System.out.flush();
System.exit(-1);
}
}
}
protected void finalize(){
//Clean up
try{
in.close();
out.close();
server.close();
} catch (IOException e) {
System.out.println("Could not close.");
System.exit(-1);
}
}
public int getBoundLocalPort(){
return server.getLocalPort();
}
}
NetComm.java
import cresco.ai.att.ccm.core.CCMMain;
import cresco.ai.att.ccm.gui.DataPanel;
import java.io.*;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
import javax.servlet.*;
import javax.servlet.http.*;
import java.applet.*;
public class NetComm extends JApplet{//HttpServlet{
private CCMMain hMain;
private DataPanel dpLocal;
private SocketServer sockserver;
private Method serverMethod;
String testStr;
Integer testInt; /*integer */
Character testChar; /*character*/
//Testing this...
ServerSocket server = null;
Socket client = null;
BufferedReader in = null;
PrintWriter out = null;
String line;
#Override
public void init(){
sockserver = new SocketServer(this);
//For offline debug (should be disabled in a release to the webapp):
//initSocketServer is commented out in the release version and
//invoked in the Eclipse testbed version. In the webapp,
//initSocketServer is invoked from javascript (see below js sockPuppet())
//////initSocketServer(0);
String msg = "Hello from Java (using javascript alert)";
try {
getAppletContext().showDocument(new URL("javascript:doAlert(\"" +
msg +"\")"));
}
catch (MalformedURLException me) { }
}
public void sendJSAlertTest(String message){
System.out.println("sendJSAlert remotely invoked, with message: " +
message);
}
public void sendJSAlert(String message){
try {
getAppletContext().showDocument(new URL("javascript:doAlert(\"" +
message +"\")"));
}
catch (MalformedURLException me) { }
}
public void initSocketServer(int portNum){
sockserver.listenSocket(portNum);
}
public void finalizeSocketServer(){
sockserver.finalize();
}
public int socket2Me(int portNum){
try {
socks.add(new ServerSocket(portNum));
return 0; //socket opened successfully
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return -1; //socket failed to open
}
}
public int getSocketServerPort(){
return sockserver.getBoundLocalPort();
}
public void showRectTest(){
try {
getAppletContext().showDocument(new
URL("javascript:overlayRect()"));
}
catch (MalformedURLException me) { }
}
public void setGUI(DataPanel d){
dpLocal = d;
}
}
MapViz.html
<html>
<head>
<title>Welcome to Geographic Midpoint Map Vizualization!</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<link href="https://google-developers.appspot.com/maps/documentation/javascript
/examples/default.css"
rel="stylesheet" type="text/css">
...google maps stuff omitted...
<script type="text/javascript">
<script type="text/javascript">
function overlayRect(){
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
}
function doAlert(s){
alert(s);
}
function testJava(){
document.ccmApplet.showRectTest();
}
function sockPuppet(){
var i = parseInt(document.getElementById("args").value,10);
alert("parsing the input args... got " + i);
if(i == NaN || i == null){
i = 0;
}
alert("passed NaN OR null block, i is " + i);
//i = 6672; //because $%*& you, that's why!
document.ccmApplet.initSocketServer(i);
//document.ccmApplet.listenSocket(i);
alert("inittializing socket server...");
//queryPort();
alert("querying port...");
document.ccmApplet.finalizeSocketServer();
//document.ccmApplet.finalize();
alert("finalizing socket server...");
}
function queryPort(){
var d = document.getElementById("debug");
var s1 = "Last port opened was: ";
//var s2 = document.ccmApplet.getLastBoundPort();
var s2 = document.ccmApplet.getSocketServerPort();
var sFinal = s1.concat(s2);
d.value = sFinal;
}
</script>
</head>
<body>
<applet width="500" height="50" name="ccmApplet" archive="CCM.jar"
code="cresco.ai.att.ccm.io.NetComm" MAYSCRIPT></applet>
<p></p>
<canvas id="myCanvas" width="200" height="100"></canvas>
<div id="map_canvas"></div>
<input id="args" type="textentry" value="" />
<button height="50" width="50" onClick="sockPuppet()">Test Socket
Creation</button>
<input id="debug" type="debugthingy" value="debug area..." />
<button height="50" width="50" onClick="testJava()">Test Java Callback</button>
</body>
</html>
In the webapp, I fill in the args input with a valid port number on the local machine and press the Test Socket Connection button which invokes the sockPuppet() javascript. This should create a ServerSocket and bind it to the specified port, which I then separately connect my desktop client app to via SocketClient.listenSocket. The result from Eclipse in the desktop app context is "awesome sendJSAlertTest" and in the appletviewer context is the output "sendJSAlert remotely invoked, with message: Hello Client, I'm a Server!". The webapp, invoking sendJSAlert(), should call the javascript alert function on the same message, creating a popup box with the message "sendJSAlert remotely invoked, with message: Hello Client, I'm a Server!" but instead nothing happens in the browser (nor the Chrome java or javascript debug consoles), and the desktop app output is null instead of "awesome sendJSAlert" as expected
So the question: What might be the cause of the different results? I know the browser's security sandbox could be an issue, but I've included a permissions file which should allow communication via sockets on any localhost port:
grant {
permission java.net.SocketPermission
"localhost:1024-",
"accept, connect, listen, resolve";
};
It's certainly possible though that I have not applied the permissions properly (I used the sun policytool gui); what exactly needs to be done in the applet code (if anything) to apply the permissions? Could a security problem result in the lack of response I'm seeing? I'd expect an exception to be reported in Chrome's java debug console, but there weren't any...
any help would be much appreciated, thanks!
-CCJ
UPDATE:
Okay, some new information: I ran the applet again in Chrome with the javascript console open (could have sworn I tried this before without effect, but evidently not) and received the following console output--
"Uncaught Error: java.security.AccessControlException: access denied
("java.net.SocketPermission" "<myipaddress>:4218" "accept,resolve") MapVizApp.html:154
sockPuppet MapVizApp.html:154 onclick MapVizApp.html:179 Uncaught Error: Error
calling method on NPObject. sockPuppet onclick "
So the question now is why am I tripping this security exception? The policy file with the permissions given above is in the same working directory as the html page and the jar file containing the applet, and I added the following to my system's JRE security policy file
//Grants my NetComm applet the ability to accept, connect, and listen on unpriv. ports
grant codeBase "file:${user.home}\Desktop\dev\invention\ATT\MapViz\CCM.jar" {
permission java.net.SocketPermission
"localhost:1024-",
"accept, connect, listen, resolve";
};
I haven't yet signed the applet, but it was my understanding that if the policy files are in order an applet doesn't need to be signed... if I'm wrong on that please let me know. Anyway, does anyone have any suggestions as to why this security exception is being thrown despite the policy files having the above granted permissions? Is there a naming convention for policy files in working directories that the JRE looks for? My working directory policy file for now is just named ccmPolFile, but I'm not clear on how the JRE is supposed to locate it; is there something I need to add to the applet code to point the JRE at the intended working directory policy file? Further, shouldn't the system policy file grant that I added be enough by itself to satisfy socket permissions for my applet inside CCM.jar?
UPDATE 2:
I signed the applet and added the line policy.url.3=file:${user.home}\Desktop\dev\invention\ATT\MapViz\ccmPolFile.policy to my java.security file in ${java.home}/lib/security (via http://docs.oracle.com/javase/tutorial/security/tour2/step4.html#Approach2 this is apparently how the JRE locates policy files to load)... sadly, the result is exactly the same security exception. The only thing left that I know of is
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
// perform the security-sensitive operation here
return null;
}
});
which should let me do almost anything since the applet is now signed. I wanted to keep signing out of the equation, but policy files aren't working for some reason. I'll be back shortly with how that works out
righto, so following my update 2 above, I change the listenSocket() method in SocketServer.java code to
public void listenSocket(int portNum){
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
int portNum = 4444;
try{
System.out.println("#server Trying to create socket bound to port " + portNum);
server = new ServerSocket(portNum);
System.out.println("the attached socket port is " + server.getLocalPort());
} catch (IOException e) {
System.out.println("Could not listen on port " + portNum);
System.exit(-1);
}
try{
client = server.accept();
System.out.println("Connection accepted!");
} catch (IOException e) {
System.out.println("Accept failed: " + portNum);
System.exit(-1);
}
try{
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Accept failed: " + portNum);
System.exit(-1);
}
while(portNum==4444){
try{
System.out.println("trying to read from inputstream...");
line = in.readLine();
System.out.println(line);
//Now that we have a method name, invoke it
try {
serverMethod = hNet.getClass().getDeclaredMethod(line,
String.class);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
serverMethod.invoke(hNet, "Hello from Javascript invoked by the
desktop app!");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Send data back to client
out.println("awesome " + line);
//System.out.println(line);
//System.out.flush();
} catch (IOException e) {
System.out.println("Read failed");
System.out.flush();
System.exit(-1);
}
}
return null;
}
});//end doPrivileged
}
obviously this is an unsafe kludge, but it does the trick-- I receive no security exception, and the desktop app prints "awesome sendJSAlert" so I know IO is working between the client and server contexts via sockets. The actual js alert function didn't fire, but I think that has something to do with the horrid infinite while loop in listenSocket() above...
Take home message: for some reason, to establish socket connections from an applet in google chrome I needed to sign the applet AND use AccessController.doPrivileged() to invoke my security sensitive code, despite having set my local policy and security files to grant my applet those permissions
googlers see refs:
http://www.coderanch.com/how-to/java/HowCanAnAppletReadFilesOnTheLocalFileSystem
http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html
http://www-personal.umich.edu/~lsiden/tutorials/signed-applet/signed-applet.html
http://docs.oracle.com/javase/tutorial/security/tour2/step4.html
UPDATE: Finally working 100% :D I changed the listenSocket() method above in SocketServer.java to this:
public void listenSocket(int portNum){
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
int portNum = 4444;
try{
System.out.println("#server Trying to create socket bound to port " + portNum);
server = new ServerSocket(portNum);
System.out.println("the attached socket port is " + server.getLocalPort());
} catch (IOException e) {
System.out.println("Could not listen on port " + portNum);
System.exit(-1);
}
try{
client = server.accept();
System.out.println("Connection accepted!");
} catch (IOException e) {
System.out.println("Accept failed: " + portNum);
System.exit(-1);
}
try{
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out = new PrintWriter(client.getOutputStream(), true);
} catch (IOException e) {
System.out.println("Accept failed: " + portNum);
System.exit(-1);
}
try {
line = in.readLine();
System.out.println("line is " + line + " from the inputstream to the
serversocket");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(line != null){
System.out.println("trying to read from non-null inputstream...");
//line = in.readLine();
System.out.println(line);
//Now that we have a method name, invoke that bitch!
try {
serverMethod = hNet.getClass().getDeclaredMethod(line, String.class);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
serverMethod.invoke(hNet, "Hello From Javascript invoked by a desktop
app!");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Send data back to client
out.println("awesome " + line);
//System.out.println(line);
//System.out.flush();
}
return null;
}
});//end doPrivileged
}
The server.accept() method blocks until a connection is made anyway, so for this scenario where I only want to pass one command at a time to the serversocket inputstream a while loop didn't make sense. The change to an if allowed the program to actually continue on to the java.reflect stuff which invokes a method in the applet which invokes javascript functions directly. Since the port is still hard-coded and the applet utilizes doPrivileged(...) this is still not a great solution, but it does satisfy the use case of invoking javascript in a web browser from a desktop java application via a java applet bridge so it makes for a good springboard into more robust implementations!
Related
I'm trying to connect to my FTP server in Java SE 1.8. To do so I use this method :
private void connectFTP() {
String server = "ftp.XXXXXXXXXX.site";
int port = 21;
String user = "XXXX";
String pass = "XXXX";
if(!ftpConnexionSuccess.get())
{
client = new FTPClient();
client.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
try {
client.connect(server, port);
ftpConnexionSuccess.set(client.login(user, pass));
if (!ftpConnexionSuccess.get()) {
System.out.println("Could not login to the server");
return;
}
else
{
System.out.println("LOGGED IN SERVER");
client.changeWorkingDirectory("/crypto");
listenedFile = getListenedFile();
System.out.println(listenedFile.getName());
if(listenedFile != null)
{
baseFileTimeStamp.set(listenedFile.getTimestamp().getTimeInMillis());
}
System.out.println(baseFileTimeStamp);
}
} catch (Exception ex) {
System.err.println("FTP connection error : Sleeping for 5 seconds before trying again (" + ex.getMessage() + ")");
ex.printStackTrace();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {e.printStackTrace();}
try {
client.disconnect();
} catch (IOException e) {e.printStackTrace();}
connectFTP();
}
}
}
It works great when I'm on Eclipse and when I export the app on my Windows 10.
Nonetheless, when I try to launch the app on my AWS Webmachine I get a null pointer exception at "listenedFile". The method to listen to this file is the one below.
private FTPFile getListenedFile() {
FTPFile returnedFile = null;
try {
for(FTPFile file : client.listFiles())
{
if(file.getName().contains("filetolisten.txt"))
returnedFile = file;
}
} catch (Exception e) {
System.out.println(e.getMessage());
e.printStackTrace();
try {
client.disconnect();
} catch (IOException e1) {e1.printStackTrace();}
connectFTP();
return getListenedFile();
}
return returnedFile;
}
I thought it was because of the line
client.configure(new FTPClientConfig(FTPClientConfig.SYST_UNIX));
I tried to delete the line, and to replace SYST_UNIX with SYST_NT, but nothing worked.
I tried to delete the line, and to replace SYST_UNIX with SYST_NT, but nothing worked. Also updated Java, updated the common-nets library. Nothing worked
I have two classes - Provider and Requester:
Provider
import java.io.*;
import java.net.*;
public class Provider {
ServerSocket providerSocket;
Socket connection = null;
ObjectOutputStream out;
ObjectInputStream in;
String message;
Provider() {
}
void run() {
try {
// 1. creating a server socket
providerSocket = new ServerSocket(2004, 10);
// 2. Wait for connection
System.out.println("Waiting for connection");
connection = providerSocket.accept();
System.out.println(
"Connection received from " + connection.getInetAddress().getHostName());
// 3. get Input and Output streams
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
in = new ObjectInputStream(connection.getInputStream());
sendMessage("Connection successful");
// 4. The two parts communicate via the input and output streams
do {
try {
sendMessage(
"Please enter the phrase you wish to echo or the word FINISHED to exit");
message = (String) in.readObject();
sendMessage(message);
} catch (ClassNotFoundException classnot) {
System.err.println("Data received in unknown format");
}
} while (!message.equals("FINISHED"));
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
// 4: Closing connection
try {
in.close();
out.close();
providerSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
System.out.println("server>" + msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) {
Provider server = new Provider();
while (true) {
server.run();
}
}
}
Requester
import java.io.*;
import java.net.*;
import java.util.Scanner;
public class Requester {
Socket requestSocket;
ObjectOutputStream out;
ObjectInputStream in;
String message;
Scanner input;
Requester() {
input = new Scanner(System.in);
}
void run() {
try {
// 1. creating a socket to connect to the server
requestSocket = new Socket("127.0.0.1", 2004);
System.out.println("Connected to localhost in port 2004");
// 2. get Input and Output streams
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
in = new ObjectInputStream(requestSocket.getInputStream());
// 3: Communicating with the server
try {
message = (String) in.readObject();
System.out.println("server>" + message);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
do {
try {
message = (String) in.readObject();
System.out.println(message);
message = input.nextLine();
sendMessage(message);
message = (String) in.readObject();
} catch (ClassNotFoundException classNot) {
System.err.println("data received in unknown format");
}
} while (!message.equals("FINISHED"));
} catch (UnknownHostException unknownHost) {
System.err.println("You are trying to connect to an unknown host!");
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
// 4: Closing connection
try {
in.close();
out.close();
requestSocket.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
void sendMessage(String msg) {
try {
out.writeObject(msg);
out.flush();
System.out.println("client>" + msg);
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
public static void main(String args[]) {
Requester client = new Requester();
client.run();
}
}
The programs are basically meant to communicate with each other. The idea is that they each 'connect' with each other via sockets and the user should be able to enter something in the console window of Provider and have it echoed back onto the console of Requester. However, I am getting the following errors:
Provider
java.net.SocketException: Permission denied: listen failed
Requester
java.net.ConnectException: Connection refused: connect
(I can provide the rest of the errors if it would help in fixing the issue).
I have tried having the classes in the same project folder, in separate folders, and in different workspaces. I have also tried using Eclipse EE (Neon) and the SE (Oxygen). Recently, I have been having problems with ports and sockets (most notably with Tomcat and encountering the 'Cannot find free socket for debugger' in Eclipse). Would that have something to do with me being unable to run these programs?
Check your firewall settings. I was having similar problems when trying to use sockets. Make sure any relevant resources aren't blocked.
You might also want to run the command:
netstat -ano | findstr :2004
to check if that port is mistakenly in use already.
I have two classes, the first is the server and the second diffuse a video. In the server class, I have a System.out.println before launch the diffusion. I want in the second class to launch the video only if in on console is written "Client" with a certain IP address after.
How can I do this?
Server
try {
serverSocket = new ServerSocket(Constants.PORT);
}
catch (IOException e){
e.printStackTrace();
}
while (true) {
try{
socket = serverSocket.accept();
}
catch (IOException e) {
System.out.println("I/O Error : " + e);
}
System.out.println("Client " + socket.getInetAddress() + " connected !");
new DiffusionThread (socket).start();
}
DiffuseVideo
try {
Util.transfertVideo(
new FileInputStream("chrono.flv"),
socket.getOutputStream(),
socket
);
} catch (SocketException e) {
System.err.println(this.getId() + ": " + e);
System.out.println("\n Client " + socket.getInetAddress() +" disconnected !");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thank you all.
Sorry if I just answer instead of commenting.
But you could just insert some if-clauses to set some boolean to true/false and of course creating the setter/getter for that.
Maybe like this:
if (socket.getInetAsdress() == "1.2.3.4") {
connected = true;
}
Or whatever. I do not know right know if there are some methods already implented where you can check that and it returns you some boolean. But notice that you must init the boolean - in my case - connected at the beginning and do not forget to set it to false each time you will establish a new connection.
After that you can easily check the boolean in your second class somehow like that:
if (Server.getBoolean == true) {
//code to execute
} else {
System.out.println("Connection Error!");
}
Or if you use public on that boolean instead of setter/getter:
if (connected == true) ...
Hope this could help you. Let me know if you need something else.
I'm trying to send a stream of Strings from a Java server to a C++/CLI Client, but before doing that I wanted to start with the simplest case, i.e. send a single String from a Java Server to a C++/CLI client and display it.
The examples I found in the literature or in tutorials didn't work for me, knowing that the same Java Server communicated easily with another Java Client (either on the same machine or on different machines).
Without further ado, here's my Code:
the Java Server Side: SendStringToCpp.java
import java.net.*;
import java.io.*;
public class SendStringToCpp {
public static void main(String[] args) {
String message = "message"; // The String that contains the information
byte[] sentBytes = message.getBytes();
System.out.println("Message: " + message);
ServerSocket s = null;
try {
s = new ServerSocket(30011);
} catch (IOException e) {
e.printStackTrace();
}
Socket s1 = null;
try {
s1 = s.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
OutputStream s1out = null;
try {
s1out = s1.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
DataOutputStream dos = new DataOutputStream (s1out);
try {
//dos.writeUTF(message); // Sending the String
dos.write(sentBytes); // Sending the bytes
} catch (IOException e) {
e.printStackTrace();
}
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
s1out.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
s1.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The C++ Client Side: ReceiveStringFromJava.cpp
#include "stdafx.h"
#include <exception>
using namespace System;
using namespace System::Net;
using namespace System::Net::Sockets;
using namespace System::Text;
using namespace System::IO;
int main(array<System::String ^> ^args)
{
Console::WriteLine(L"Creating the Socket...");
try {
//Socket^ listener = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp);
//Creates a UdpClient for reading incoming data.
UdpClient^ receivingUdpClient = gcnew UdpClient();
IPEndPoint^ RemoteIpEndPoint = gcnew IPEndPoint(IPAddress::Any, 30011);
//listener->Bind(RemoteIpEndPoint);
array <Byte>^ receiveBytes = receivingUdpClient->Receive(RemoteIpEndPoint); // get the Bytes array from the end poitn
String^ receivedString = Encoding::ASCII->GetString(receiveBytes); // retrieve the string from the received Bytes
Console::WriteLine("This is the message received {0}", receivedString);
// Console::WriteLine("this message was send from {0} on their ort number {1}", RemoteIpEndPoint->Address, RemoteIpEndPoint->Port);
}
catch (Exception^ e) {
Console::WriteLine("Error! ");
Console::WriteLine( e->ToString());
}
Console::ReadLine();
return 0;
}
And Here's the Exception printed on the Console:
http://i.stack.imgur.com/uTDqm.jpg
P.S. I tried to Bind the IPEndPoint to the Socket (it's commented above), but to no avail, and gave the same Error.
Socket^ listener = gcnew Socket(AddressFamily::InterNetwork, SocketType::Dgram, ProtocolType::Udp);
.
.
listener->Bind(RemoteIpEndPoint);
You need to use the UdpClient constructor that allows binding to a listening port.
Quoting MSDN (emphasis mine):
Initializes a new instance of the UdpClient class and binds it to the
local port number provided.
UdpClient^ receivingUdpClient = gcnew UdpClient(30011);
// specify the port both here ^^^^^ and here vvvvv
IPEndPoint^ RemoteIpEndPoint = gcnew IPEndPoint(IPAddress::Any, 30011);
array <Byte>^ receiveBytes = receivingUdpClient->Receive(RemoteIpEndPoint);
I'm setting up a basic client server program. Right now the client is simply sending an object with a command string in it to the server and the server is acknowledging it. This is done using a JFrame with buttons on it. It seems to work ok, except the client seems to be sending multiple requests instead of just one.
Inner class within my Client code:
private class CommandHandler implements ActionListener{
FTPCommand c;
ObjectOutputStream oos;
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd == "DIR"){
c = new FTPCommand("DIR");
}
if (cmd == "CHDIR"){
String newDirectory = JOptionPane.showInputDialog("Please enter directory to change to:");
c = new FTPCommand("CHDIR", newDirectory);
}
try {
oos = new ObjectOutputStream(sock.getOutputStream());
oos.writeObject(c);
oos.flush();
//System.out.println("Command: " + c.getCommand() + ", sent successfully");
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
Server:
public void run(){
ObjectInputStream in;
try {
in = new ObjectInputStream(sock.getInputStream());
FTPCommand cmd = (FTPCommand) in.readObject();
System.out.println("Received command: " + cmd.getCommand() + " at " + System.currentTimeMillis());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
So if I click on the DIR button just once, this is the output I get, although sometimes it might just be one or two lines:
Received command: DIR at 1390572358017
Received command: DIR at 1390572365578
Received command: DIR at 1390572377229
Why is it sending multiple requests?
Check inside the constructor of FTPCommand; that how many time... it has been called... If thrice .... trace the calling methods.
It turns out that this was the result of the client holding onto previous connections, and sending requests through all open sockets.