Im working on building my own GUI program that talks to my pc from a tablet. I have the server side done in java but my problem is on the client side.
I want to send data out the PrintWriter to the server from a separate method.
I have accomplished sending in the code below (it sends 'a') but i cant figure out how to send it from a separate method. i believe its a basic java scope problem that im not understanding. i would really appreciate the help.
I have tried moving the variables into other scopes.
import java.io.*;
import java.net.*;
public class TestClient {
public static void main(String[] args) {
String hostName = "192.168.0.3";
int portNumber = 6666;
try ( //Connect to server on chosen port.
Socket connectedSocket = new Socket(hostName, portNumber);
//Create a printWriter so send data to server.
PrintWriter dataOut = new PrintWriter(connectedSocket.getOutputStream(), true);
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))
) {
//Send data to server.
dataOut.println("a");
}catch (UnknownHostException e) {
System.err.println("Don't know about host " + hostName);
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to " +
hostName);
System.exit(1);
}
}
public static void sendToServer() {
//I want to control the print writer from this method.
//I have failed i all the ways i have tried.
}
}
You could move the Printer-Code (try try block) into the sendToServer-method and call it via
TestClient client = new TestClient();
client.sendToServer("this is a test");
Of course the sendToServer method needs to accept a parameter then. Even better would probably be to put the main method into a Starter class and decouple it from the Client-Class that you use for sending the data.
Related
I have created a very very basic java server with tutorials. The goal is to let gamemaker studio 2 clients connect and communicate with that server. I have more experience with GML.
So the server is starting(java) up and the client(GMS2) is connecting succesfully. I have buildin some checks to make sure. If the client send a message to the server, the server never gets it, until the clients disconnect.
this is the java code:
import java.net.*;
import java.io.*;
public class GameServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(6666);
Socket client = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
out.println("hello gamemaker studio: "); //the clients receive this message
while(true) {
System.out.println("in while loop");//the server console prints this message
String string = in.readLine();//keeps stuck on this
//after client disconnect, all messages the client has sent are displayed in the console
System.out.println("reading string:" + string);
if (string == null) { break; }
out.println("we have received this answer: " + string );
System.out.println("stopped");
}
}
}
For some reason i don't know it is keeps stuck on this line:
String string = in.readLine();
I crafted a java client to test it. Everything works fine with a java client.
So there has to be something wrong with the gamemaker code
I'm trying to use SSL with IMAP in java. I do not want to use the IMAP class.
For some reason, when I send the n th message, I receive the answer to message n-2, and not to message n-1. Which means that I don't receive any answer to the first message sent until I send the second message. Can anyone spot what's wrong in the following minimal code ? (It is indeed minimal, apart from the println, which, I guess, help debugging)
import java.io.*;
import javax.net.ssl.*;
public class Mail{
static String server = "imap.gmail.com";
static String user = "straightouttascript#gmail.com";
static String pass = "azerty75";
public static void print (PrintWriter to, String text){
System.out.println("sent : "+text);
to.println(text+ "\r");
to.flush();
}
public static void read (BufferedReader from) throws InterruptedException, IOException {
do {
String line = from.readLine();
System.out.println("received: "+line);
} while (from.ready());
}
public static void main(String[] args){
try{
SSLSocket sslsocket = (SSLSocket) SSLSocketFactory.getDefault().createSocket(server, 993);
System.out.println("Start connexion");
BufferedReader from = new BufferedReader(new InputStreamReader(sslsocket.getInputStream()));
// read(from);
PrintWriter to = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sslsocket.getOutputStream())), true);
print(to,"a1 login "+user+" "+pass);
read(from);/*exepcted:
OK gimap ready
a1 OK login#host authenticated (Success)*/
sslsocket.close();
System.out.println("End connexion");
}
catch (Exception e){
e.printStackTrace();
}
}
}
IMAP is not a pingpong protocol. The server doesn't send one line in response to one of yours.
Rather, you send commands and the server sends information. The server is permitted to send you more information than you asked for, so you can get seven responses to one command, and you can even get a response without sending a command at all, which is then called an unsolicited response. Strange phrase. Unsolicited responses are used by some servers to notify you about new mail, by more to notify you about flag changes on messages, and by (almost?) all to notify you that they're about to close your connection.
I'm now processing a client-server communication in Java, by using Socket and ServerSocket objects.
Once the server has been initialised, it puts on hold with new clients through the accept() method, from ServerSocket class; I immediately provide to put this socket in a client map on the server:
- keys: ClientNode(Socket s, CommunicationChannels channels);
- values: Info();
(CommunicationChannels contains ObjectOutputStream and ObjectInputStream from socket; Info contains some information about client, as username, messages etc..).
Given that, at the very beginning, the socket does not have any other information on the client besides the socket itself, first insertion on the map is map.put(ClientNode, null). I will fill the field "value" afterwards.
Now, on Client class, I am going to initialise a Socket("127.0.0.1", 13001), namely with a loopback address and gate 13001. Once communication channels have been initialised, client connects to the server.
Once the client starts, he takes a remote copy of the server through RMI (stub) libraries and the server makes a register() method available: it would allow to use this method to write requested information (from the clients) on the map.
How can the client go back to the socket with which it has been registered on the server? Frankly speaking, I supposed that accept() method from ServerSocket could take the socket established on the startup client back to the server, namely with the new Socket("127.0.0.1", 13001), but it seems to me that this does not happen.
Here you can find parts of the code, so you can better understand what I'm talking about. I've already taken into account a few things that I will share with you in case of need.
public class Server implements Runnable, RemoteServices {
...
private Map<ClientNode, Info> map = new HashMap<ClientNode, Info>();
...
public void run() {
ServerSocket ss = null;
try {
ss = new ServerSocket();
while (true) {
if (!ss.isBound()) {
ss.bind(new InetSocketAddress(ipServer, port));
}
Socket client = ss.accept();
CommunicationChannels channels = new CommunicationChannels(new ObjectOutputStream(client.getOutputStream()), new ObjectInputStream(client.getInputStream()));
map.put(new ClientNode(client, channels), null);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// RemoteServices implementa Remote e mette a disposizione register()
public void register(Info info) throws RemoteException {
// TODO
}
public class Client implements Runnable {
...
...
#Override
public void run() {
Socket client = null;
try {
client = new Socket(ipServer, port);
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
Registry registry = LocateRegistry.getRegistry("127.0.0.1");
stub = (RemoteServices) registry.lookup("remoteObject");
Info info = new Info();
info.setID(getID());
info.setUsername("Giordano");
stub.register(info);
} catch (IOException e) {
System.err.println("Spiacente: il server ha terminato l'esecuzione.");
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}
}
Remarks:
I have not included the code of some classes because I thought it was superfluous; for example the "info" class is just a series of "getter and setter" of some fields; the CommunicationChannels class represents communication channels of the client, taken directly from the socket, etc ..
The server, after the accept(), does not instantiate any thread to communicate with the client because communication has to come afterwards. However, if there was a way to solve my problem with a thread of communication I would find a way to fix it.
My question starts from the need to make interact 2 clients with a server without using more PCs; therefore all clients will have the IP loopback and therefore I cannot use the IP address as a discriminating between two sockets, otherwise I would have already solved it.
In other words, I know that methods as socket.getInetAddress().getHostAddress() can help me to distinguish between two socket, but if I initialise two clients on the same PC I have to use loopback address and the method always returns "127.0.0.1".
The register() method is obviously incomplete even in the signature; once understood how to compare the server socket and client one through a Serializable discriminating object (like the hashcode()) probably I might put it in the arguments of the method, so you can easily make the comparison.
Finally, main() methods:
public static void main(String[] args) {
Server server = new Server("127.0.0.1", 13001);
RemoteServices stub;
try {
stub = (RemoteServices) UnicastRemoteObject.exportObject(server, 0);
Registry registry = LocateRegistry.getRegistry();
registry.bind("remoteObject", stub);
(new Thread(server)).start();
} catch (RemoteException e) {
System.err.println("Verificare l'apertura dei registri");
} catch (AlreadyBoundException e) {
System.err.println("Server già attivo. Controllare che i registri siano chiusi correttamente.");
}
}
public static void main(String[] args) { Client client = new Client("127.0.0.1", 13001);
new Thread(client).start();
}
I really hope everything is clear and that you can help me.
What can cause this to happen?
I moved my laptop to a friends house to work on this project. I opened the same port on his xfinity router, and changed all areas of my code to his IP. However it appears that the client is sending a message and the server has never getting past this part of code
System.out.println("running server!");
int nreq = 1;
try{
//SET ME PORT
ServerSocket sock = new ServerSocket(7332);
for(;;){
Socket newsock = sock.accept();
System.out.println("Creating thread...");
//Broken Old Login crap, needs reworked for map n stuff anyhow now
// Thread t = new ThreadHandler(newsock, nreq);
Thread t = new RequestInterpreter(newsock, nreq);
//t.run();
t.start();
nreq++;
}
}
catch(Exception e)
{
e.printStackTrace();
}
It never gets to print "Creating thread". I'm not sure where to begin with what could be going wrong here?
The only thing that has changed is the house, IP, router, and internet. Works everywhere else. What about those changing could block the client from sending a
Here is a test client I wrote also.
import java.io.DataInputStream;
import java.io.PrintWriter;
import java.net.Socket;
public class testClientConnection {
public static void main(String[] args) {
System.out.println("Starting testConnection");
try{
Socket s = new Socket("xx.xx.xx.xxx", 7332);
DataInputStream fromServer = new DataInputStream(s.getInputStream());
PrintWriter toServer = new PrintWriter(s.getOutputStream(), true);
toServer.println("account name");
toServer.println("password");
toServer.println("Login");
System.out.println("Sent message...");
String response = fromServer.readLine().toString();
//Toast the result here? //testing
System.out.println("response: " + response);
if (response.equals("Login Success")) {
System.out.println("Login Success!!!");
}
}
catch(Exception e){ /
}
}
}
HUGE UPDATE!
Ok so my client was an android phone and I turned the wifi off, so it fell onto 4g-LTE. Then it worked. So... Something is blocking the client side code. What might that be?
The firewall on your friend's router is the usual suspect.
Second suspect is the firewall on the target machine.
Try disabling those.
The problem will be NAT on the router.
Servers don't work behind NAT devices unless you set up port-forwarding so that the router knows where to send an incoming request from outside.
I have a server-client pair and I want to create a listener on the client end for new server responses. I am not sure how to do this, right now I can only interact in a direct synchronous way.
Here is the server:
public class TestServer {
public static void main(String[] args) throws Exception {
TestServer myServer = new TestServer();
myServer.run();
}
private void run() throws Exception {
ServerSocket mySS = new ServerSocket(4443);
while(true) {
Socket SS_accept = mySS.accept();
BufferedReader myBR = new BufferedReader(new InputStreamReader(SS_accept.getInputStream()));
String temp = myBR.readLine();
System.out.println(temp);
if (temp!=null) {
PrintStream serverPS = new PrintStream(SS_accept.getOutputStream());
serverPS.println("Response received: " + temp);
}
}
}
}
As you can see, it sends a response when it gets one. However in general I won't be sure when other servers I use send responses, so I would like to create an asynchronous listener (or at least poll the server for a response every half-second or so).
Here is what I'm trying on the client end:
protected static String getServerResponse() throws IOException {
String temp;
try {
BufferedReader clientBR = new BufferedReader(new InputStreamReader(mySocket.getInputStream()));
temp = clientBR.readLine();
} catch (Exception e) {
temp = e.toString();
}
return temp;
}
And just for reference, yes, sending over data from client to server works fine (it System.out's the data correctly). However, when I call the above function to try and retrieve the server response, it just hangs my application, which is an Android application in case that's relevant.
What I want from a function is just the ability to ask the server if it has data for me and get it, and if not, then don't crash my damn app.
On the client side create a ConnectionManager class which will handle all the socket I/O. The ConnectionManager's connect() method will create and start a new thread which will listen for server responses. As soon as it will receive a response it will notify all the ConnectionManager's registered listeners. So in order to receive asynchronously the server responses you will have to register a listener in ConnectionManager using its register(SomeListener) method.
Also, you can have a look at JBoss Netty which is an asynchronous event-driven network application framework. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.