#ServerSockets

1 messages ยท Page 1 of 1 (latest)

tardy sinewBOT
#

<@&987246399047479336> please have a look, thanks.

tardy sinewBOT
#

While you are waiting for getting help, here are some tips to improve your experience:

Code is much easier to read if posted with syntax highlighting and proper formatting.

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.

sharp pier
#

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.

proud steeple
#

As far as i know, it Returns a (successfully) connected Socket

proud steeple
sharp pier
proud steeple
proud steeple
# sharp pier yes

So you can for example test with that if the Computer is connected with the Internet or for what can it be used?

sharp pier
proud steeple
sharp pier
#

The accept() method is used to accept a connection request from a client

proud steeple
#

Yes, but with the timeout and the exeption, for what could i use this exeption, for example in a try-catch

sharp pier
#

Idk, you can just use it in try and catch and continue ur loop until a client tried to connect

#

Or just log it

proud steeple
#

Okay

sharp pier
#

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

sharp pier
#

A NullPointerException you not use as well in other cases, so i not really get ur question here

proud steeple
sharp pier
proud steeple
#

Ahh, yes, it was yourIpOrWeb.isReachable() right? Or could i run it without an address?

sharp pier
proud steeple
iron echo
#

I think

sharp pier
iron echo
#

Yeah just checked, you can

#

getByName threw me for a second

proud steeple
iron echo
void basin
#

localhost has an ip aswell

proud steeple
#

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

iron echo
#

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)

proud steeple
#

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

void basin
#

if u do that , u wont even reach the router

proud steeple
#

But could you also "ping" the Router or so, and not the own PC?

proud steeple
void basin
#

yeah your modem has an ip adress

#

your the programmaer, if u want a in between step , code it ๐Ÿ™‚

proud steeple
#

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

drowsy atlas
#

thread safe array list

proud steeple
#

And i forgot, the Client handler implements the Runnable and is started after it is created with the Client socket

proud steeple
#

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

proud steeple
#

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

drowsy atlas
#

why not using try-with-resource

proud steeple
drowsy atlas
#
try (PrintWriter printWriter = new PrintWriter(socket.getOutputStream()) {
  // use printWriter here, auto closing even if exception happens ...
}
proud steeple
#

Uhh, nice

#

But He would also have to handle when there is no such Client in the list, with that it is catched

drowsy atlas
#

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

proud steeple
#

Ahh, yes

drowsy atlas
#
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

proud steeple
#

Yes

#

I forgot that

drowsy atlas
#

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

pure cryptBOT
#
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:

  1. The socket is associated with a SocketChannel. In that case, interrupting a thread writing to the output stream will close the underlying channel and cause the write method to throw ClosedByInterruptException with the interrupt status set.
  2. The socket uses the system-default socket implementation and a virtual thread is 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 throw SocketException with the interrupt status set.

Closing the returned OutputStream will close the associated socket.

drowsy atlas
#

Closing the returned OutputStream will close the associated socket.

drowsy atlas
proud steeple
sharp pier
tardy sinewBOT
#

Activities have been reset.

crystal cove
#

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();
                }
            
            }
        }

    }
tardy sinewBOT
# crystal cove ```java private class ClientHandler extends Thread implements MessageHandler { ...

Detected code, here are some useful tools:

Formatted code
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();
      }
    }
  }
}
crystal cove
#

well that not important in your case its just an example i had from when i last worked with sockets

#

they did examples for string communication and i modified what i did based on this

iron echo
#

btw, you should look into NIO and not do networking the traditional IO way with ServerSocket

iron echo
#

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)

kind otter
iron echo
#

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)

iron echo
#

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

rigid sky
#

Java 13 ๐Ÿ‘€

iron echo
#

Yeah, I have played around with it using virtual threads already awhile ago, traditional NIO using selectors was still the better choice