I have a questions that is perhaps indicative of my lack in experience and the fact that I am still a student.
I established a socket connection client side(server is already running) and after making the connection on the client side I immediately go to a different Form(that is also based on the client side) where I want to verify userName and password against database on the server side. Problem is, I feel that I do not want to make the connection again as I have already done this on the previous Form
clientSocket = new Socket(hostAdress, 7777);
How can I 'carry over' the fact that I have a connection already to the new form so that I just create and input and output stream without making the connection again on the new form.
Sorry, hope this question makes sense
Kind regards
Arian
Create a method like this:
public Socket getSocket() {
return clientSocket;
}
and call it from the other class (assuming that you have a reference to that object.
or static variable:
private static Socket clientSocket = new Socket(hostAdress, 7777);
and as Binyamin wrote, create a method , but in this case it would be static method
Related
Edit: Removed startHandshake(); as it's irrelevant to the question and rarely needed (for example, not in my case)
I have a rather specific and rare client-server protocol (over TCP).
I've implemented it using SSLSocket.
Now, I foresee that I might need to use the same protocol over an un-encrypted connection.
My problem is that the class implementing the protocol has a field: public SSLSocket currentSocket;
(and then the methods in my client class do all sorts of .read(), .write(), flush()...)
I thought about changing the field type, like so: public Socket currentSocket;
However, then, the problem is that my connection procedure is incompatible:
public static void connect () {
currentSocket = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
...
java.net.Socket 's default constructor obviously doesn't accept keystore stuff
I don't want to re-implement my whole client just for this difference...
One thought I have is, when I need a plaintext Socket, to create an SSLSocket with no encryption.
I don't know if that's a professional way of doing it or if it will even work (the server will expect a plaintext client socket in the new use case)
My other idea is to define two fields, one for plaintext socket, one for SSL socket and then use logic to link the in/out streams to the correct field, as needed. However, that will result in a "hanging" field. If you use SSL, there will be a redundant field Socket plaintextSocket and vice-versa...
Is there a way to make my currentSocket field more abstract, so that I can define it in the same client, then instruct a slightly different client code path depending on a known variable (something like needSSLsocket=true) for the instantiation and connection?
SSLSocket extends Socket, so you can assign an SSLSocket object to a Socket variable. You are right to change your currentSocket field to a Socket. Simply use another variable to handle the SSLSocket when needed, eg:
public static void connect () {
if (needSSLsocket) {
SSLSocket ssl = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
ssl.startHandshake();
...
currentSocket = ssl;
/* or:
currentSocket = SslUtils.getSSLsocket(host, port, keystoreFile, keystorePass, pkPass);
((SSLSocket) currentSocket).startHandshake();
...
*/
} else {
currentSocket = new Socket(host, port);
}
...
}
If I have created class like this,
public class UserManagement{
Socket clientSocket;
public UserManagement(Socket soc,String usrN){
clientSocket = soc;
}
}
The application needs to maintain multiple clients,
So Every time it accepts a connection with
ServerSocket ser = new ServerSocket(1234);
Socket soc = ser.accept();
Will an array of UserManagement class, handle the socket.
I mean will it be possible to create an array and access the sockets individually.
Is that possible? I am not asking for advice to develop multithreaded client handler instead I'm asking if it is possible or not.
If yes what are PreCautions I will need to take.
OK. I feel dumb. I cannot find what I'm looking for.
I am opening 50 ServerSockets and adding them to a List of ServerSockets:
ServerSocket ss = new ServerSocket(getPortNumber());
SOCKETS.add(ss);
I get that I need a new thread for each connection:
new Thread() {
public void run() {
ServerSocket ss = new ServerSocket(getPortNumber());
while(true) {
Socket client = ss.accept();
//handle client
}
}.start();
So, my question is, "Do I have to use a while loop until I get a connection?"
I mean, is there a way to listen for an attempt to connect before using the ss.accept to assign Socket client?
Do I have to use a while loop until I get a connection?
It depends. If you're only expecting one connection you don't need a while loop: otherwise, you do.
I mean, is there a way to listen for an attempt to connect before using the ss.accept to assign Socket client?
The question doesn't make sense. That's what accept() does.
NB creating the ServerSocket already puts the port into listening state that can be connected to. But it is accept() that accepts connections, and nothing else.
The fact that you're creating 50 listening ports already indicates a severe design problem. You only need one. Don't waste system resources.
This all sounds like an XY problem.
We decided that (in our case) it is best to have a dedicated server socket for each client. Therefore, I am following the answer to this SO question:
Server Listening on Multiple Ports [Java]
Everyone is aware of socket programming in java. we write a code as below:
ServerSocket serverSocket = new ServerSocket(1234);
Socket server = serverSocket.accept();
We know that we create object of serverSocket and next we write serverSocket.accept(); code to receive client request. we know that serverSocket.accept(); wait until new request comes.
but my question is : what serverSocket.accept(); method does internally? might be is running in while loop ? how server identify that any new request is came to serve ? what is the internal implmentation of serverSocket.accept(); method? Any One has idea about this?
On Linux, the ServerSocket.accept() ultimately (in native code) does an accept syscall (see man 2 accept) which blocks waiting for a suitable incoming connection.
There is no while loop in the Java code or in the native code. I've no idea what happens inside the Linux kernel, but at that point this is no longer a Java question.
The same would probably apply for Java on Windows, and for C# or any other programming language that you cared to consider.
You can find this by your own.
public Socket accept() throws IOException {
if (isClosed())
throw new SocketException("Socket is closed");
if (!isBound())
throw new SocketException("Socket is not bound yet");
Socket s = new Socket((SocketImpl) null);
implAccept(s);
return s;
}
How accept() works?
The basic idea is that when the app starts a class will simply establish a socket connection to server and define output and input streams, those which should be accessed through all different activities that requires interaction so the socket must be always alive and ready.
My thoughts so far is to create a class that will simply create socket and connections:
public class connection {
private String HostIPaddress = "XXX.XXX.XXX.XXX";
private int PORT = XXXX;
public Socket sock = null;
public DataOutputStream out = null;
public DataInputStream in = null;
public void assignStreams(){
try{
sock = new Socket(getHostIPaddress(),getPORT());
out = new DataOutputStream(sock.getOutputStream());
in = new DataInputStream(sock.getInputStream());
}catch (Exception ex) {
Log.i("Connection Error",ex.toString());
}
}
}
and then from the activity that run first, create a static object of this class and all other activities can access this object.. It sounds that this would work but I was wishing for some more thoughts or feedback?
No, not a good idea. The user can switch off internet at any point in time and your class is using a network connection when one may not be needed at all. Cleaning up after the socket is also impossible. How do you know when to close() it ?
You are just better off creating these as needed. Your class also has poor encapsulation.
public Socket sock = null;
public DataOutputStream out = null;
public DataInputStream in = null;
These streams can be reassigned at any time. Protect them with getters() and setters().
I wouldn't know why it's not possible.
Wether it's a good idea or not, I don't know.
My two cents to achieve it your way is, create a singleton class.
singleton pattern example
Credits for the article go to http://www.javacoffeebreak.com/
Aside from their barebone implementation, make sure you have a method to retrieve your socket and just as important, close your socket. Which you can do when your app gets destroyed. I believe the application object's onDestroy method is a decent place to do this as from what I remember that will be the last onDestroy method called before your application is taken completely out of memory.
Having that said.. what if your application crashes? you will need to clean up somehow.
Creating a socket on demand will probably be the safest way.
Note that, if you have a socket that is always open throughout activities it is easy to forget that you need to close it. Another reason to manage the socket per activity instead of globally.