#ServerSockets
1 messages ยท Page 1 of 1 (latest)
While you are waiting for getting help, here are some tips to improve your experience:
If nobody is calling back, that usually means that your question was not well asked and hence nobody feels confident enough answering. Try to use your time to elaborate, provide details, context, more code, examples and maybe some screenshots. With enough info, someone knows the answer for sure.
Don't forget to close your thread using the command </help-thread close:1027500463647621170> when your question has been answered, thanks.
The accept() method is usually called in a loop to handle multiple connections from different clients. For example:
ServerSocket server = new ServerSocket(8080); // create a server socket on port 8080
while (true) {
Socket client = server.accept(); // wait for a client to connect
// do something with the client socket, such as reading or writing data
client.close(); // close the connection when done
}```
The accept() method blocks until a connection is made or an exception is thrown. If you want to set a timeout for the accept() method, you can use the setSoTimeout() method of ServerSocket class. For example:
```java
server.setSoTimeout(10000); // set a timeout of 10 seconds for the accept() method
If the timeout expires, a SocketTimeoutException will be thrown.
As far as i know, it Returns a (successfully) connected Socket
Now for me, this happens only when a Client is connected and is timeouted du to a Bad internet connection? Or throws it that when there is no socket found?
If the accept() method throws a Exception, it means that no client has tried to connect to the socket within the timeout. It does not mean that there is no socket found or that the client has a bad internet connection
So if after the 10 seconds no Client tried to connect to the Server it throws that?
yes
So you can for example test with that if the Computer is connected with the Internet or for what can it be used?
Thats not what you use the accept method for. You can just do InetAddress.isReachable() for testing if a computer is connected to internet
But for what can be that used?
The accept() method is used to accept a connection request from a client
Yes, but with the timeout and the exeption, for what could i use this exeption, for example in a try-catch
Idk, you can just use it in try and catch and continue ur loop until a client tried to connect
Or just log it
Okay
I mean i never really used it, just remember from my school some of the things. And im sure you not use the exception for anything
All good
A NullPointerException you not use as well in other cases, so i not really get ur question here
Do you maybe know how it Tests if it is connected to the internet? And is it for local host and internet or tests it for local host only?
True
Not only local, u can also test if google is reachable etc
Ahh, yes, it was yourIpOrWeb.isReachable() right? Or could i run it without an address?
InetAddress address = InetAddress.getByName("www.google.com"); // get the IP address of Google
System.out.println(address.isReachable(5000));
``` example
And how is it made for local connection in the home (so not only the PC, but also your router? (sorry for my questions, but maybe i could use it)
what do u mean
You can pass the IP address e.g. 192.168.1.123
I think
yes u can
But would this not return it from the own PC, because it knows that it is local host?
that IP isn't localhost, localhost is either "localhost", "0.0.0.0" or "127.0.0.1"
localhost has an ip aswell
So i mean it would work, even when you don't have a cable connected
Sorry if i write local host, i mean the local network
it will get the PC via the router so if you used the IP your DHCP server provided, the router will direct the traffic back to your PC
DHCP IP is (routers DHCP server provided IP e.g. 192.168.x.x)
So if i get the IP from the PC in the Network, and test it, it would send it to the Router? Because i tried that and i could use the IP, even when He wasn't connected
if u do that , u wont even reach the router
But could you also "ping" the Router or so, and not the own PC?
So i have to use an IP from the Internet, like Google?
yeah your modem has an ip adress
your the programmaer, if u want a in between step , code it ๐
Yes, you could use the socket.getHostName() and the socket, and after that change the name, or use a Client handler and have the name store there and the use in the Server class and store the Clients in an CopyOnWriteArrayList. I made it this way in my Chat app, and the hash map for sending private Messages to the named Client
thread safe array list
And i forgot, the Client handler implements the Runnable and is started after it is created with the Client socket
It should work
But why do you close the connection after one message is send?
And when you close the connection, you have to remove the client from the list
Ahh, then I read it wrong. Sorry, i am "a bit" tired and i have headache
I think it is good, because you work without a class for the Client. But i am not Sure if this will work correctly
why not using try-with-resource
What is that?
try (PrintWriter printWriter = new PrintWriter(socket.getOutputStream()) {
// use printWriter here, auto closing even if exception happens ...
}
Uhh, nice
But He would also have to handle when there is no such Client in the list, with that it is catched
his current code would throw an NPE if there is no client for that ip address
I would just move the Socket variable out of the try-with-resource and then make null checks
Ahh, yes
Socket client = clients.get(ip);
if (client == null) {
// throw or log smth or handle how you want to
// return;
}
try(PrintWriter printWriter = new PrintWriter(client.getOutputStream())) {
} catch (/*...*/) {
}
smth like this
not really sure, but do you really want to close the PrintWriter
im not sure, will it close the underlying resource?
if so it will close your socket
and you will not be able to get the Outputstream again
public OutputStream getOutputStream() throws IOException
Returns an output stream for this socket.
If this socket has an associated channel then the resulting output stream delegates all of its operations to the channel. If the channel is in non-blocking mode then the output stream's write operations will throw an IllegalBlockingModeException.
Writing to the output stream is interruptible in the following circumstances:
- The socket is
associatedwith aSocketChannel. In that case, interrupting a thread writing to the output stream will close the underlying channel and cause the write method to throwClosedByInterruptExceptionwith the interrupt status set. - The socket uses the system-default socket implementation and a
virtual threadis writing to the output stream. In that case, interrupting the virtual thread will cause it to wakeup and close the socket. The write method will then throwSocketExceptionwith the interrupt status set.
Closing the returned OutputStream will close the associated socket.
Closing the returned OutputStream will close the associated socket.
someone needs to verify
I think yes, i know that a file write (File IO) is closging after it is finished
Vector<> 
Activities have been reset.
You need to have a clientHandler on the server side to do smth with whatever data you receive from the sockets
while (running) {
System.out.println("waiting for connection");
try {
ClientHandler ch = new ClientHandler(ss.accept());
ch.start();
clients.add(ch);
System.out.println("new Transceiver connected");
} catch (SocketException e) {
// gets thrown on shutdown
System.out.println("shutdown");
} catch (Exception e) {
}
}
Client Handler should be a class that implements Runnable so you can have a dedicated Thread listening on your server for every client connected.
yes
thats why it should implement the runnable interface so you can start a new thread for every client
private class ClientHandler extends Thread implements MessageHandler {
private Socket clientSocket;
private ObjectOutputStream out;
private ObjectInputStream in;
private String clientName;
private boolean running;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
clientName = clientSocket.toString();
acceptConnection();
}
public void shutdown () {
running = false;
try {
in.close();
out.close();
clientSocket.close();
System.out.println(clientName + " shutdown");
clients.remove(this);
} catch (Exception e) {
// TODO: handle exception
}
}
private void acceptConnection () {
try {
out = new ObjectOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
out.flush();
in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
running = true;
} catch (Exception e) {
System.out.println("Something went wrong with in/out Stream config");
running = false;
}
}
@Override
public void run() {
Message msg = null;
while (running) {
try {
System.out.println(msg=in.readObject());
handle(msg)
} catch (EOFException eofException) {
shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Detected code, here are some useful tools:
private class ClientHandler extends Thread implements MessageHandler {
private Socket clientSocket;
private ObjectOutputStream out;
private ObjectInputStream in;
private String clientName;
private boolean running;
public ClientHandler(Socket socket) {
this .clientSocket = socket;
clientName = clientSocket.toString();
acceptConnection();
}
public void shutdown() {
running = false;
try {
in.close();
out.close();
clientSocket.close();
System.out.println(clientName + " shutdown");
clients.remove(this );
} catch (Exception e) {
// TODO: handle exception
}
}
private void acceptConnection() {
try {
out = new ObjectOutputStream(new BufferedOutputStream(clientSocket.getOutputStream()));
out.flush();
in = new ObjectInputStream(new BufferedInputStream(clientSocket.getInputStream()));
running = true;
} catch (Exception e) {
System.out.println("Something went wrong with in/out Stream config");
running = false;
}
}
@Override
public void run() {
Message msg = null ;
while (running) {
try {
System.out.println(msg = in.readObject());
handle(msg) } catch (EOFException eofException) {
shutdown();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
well that not important in your case its just an example i had from when i last worked with sockets
i think this would be a good resource for you to check https://www.baeldung.com/a-guide-to-java-sockets
they did examples for string communication and i modified what i did based on this
btw, you should look into NIO and not do networking the traditional IO way with ServerSocket
Mainly performance, the way you're currently doing is how Java first implemented their networking API (let's call it v1), the underlying implementation accepts a single socket at a time and polls the operating system for a socket. If 10 there are 10 sockets, you have to make 10 system calls. This is bad performance. Secondly, you have to manage everything yourself and in the past people created a new thread for each socket. This is also extremely bad for performance
To tackle this, NIO was introduced. Now instead of polling the operating system to accept each connection, Java can now load all the available sockets in 1 go. So if we have 10 sockets ready to be accepted, we can fetch all 10 in a single system call. NIO stands for non-blocking IO and it allows you to handle loads of connections using a single thread (where nothing is blocking the main thread)
Which is great for performance
If you're interested in the low level bits, look into IOCP (windows) and or EPOLL (Linux)
There's also the Asynchronous Server Socket API in Java, but that's known to be really slow in terms of performance that's why libraries like netty have dropped it / don't support it (as there's no advantages to even have it)
did we ever get to the bottom of how good IO is now that is built on tiop of NIO
Yes we should actually!
There was a JEP to address networking, would be good to link (can't remember top of my head which one and I'm on mobile rn)
Before it was using C code that was hard to maintain. It also wasn't going to work well with virtual threads and so they made a change, specifically replaced the underlying implementation (previously PlainSocketImpl with NioSocketImpl)
The new implementation, NioSocketImpl, is a drop-in replacement for PlainSocketImpl. It is developed to be easy to maintain and debug. It shares the same JDK-internal infrastructure as the New I/O (NIO) implementation so it doesn't need its own native code.
The implementation is a mix of legacy Java and C code that is painful to maintain and debug
The new implementation will be easy to adapt to work with user-mode threads, a.k.a. fibers, currently being explored in Project Loom.
Some snippets from that JEP
Java 13 ๐
Yeah, I have played around with it using virtual threads already awhile ago, traditional NIO using selectors was still the better choice