Socket etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
Socket etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

28 Mart 2023 Salı

ServerSocketFactory Sınıfı

Giriş
Şu satırı dahil ederiz.
import javax.net.ServerSocketFactory;
Soyut bir sınıftır.Kalıtım şöyle
ServerSocketFactory 
  javax.net. DefaultServerSocketFactory 
  javax.net.ssl.SSLServerSocketFactory
  org.apache.commons.net.ftp.FTPSServerSocketFactory
  org.apache.commons.net.ftp.FTPSServerSocketFactory
  

createServerSocket metodu - port + backlog + bind address
Örnek
Şöyle yaparız.
int port = 31_003;
ServerSocket serverSocket = ServerSocketFactory.getDefault()
  .createServerSocket(port, 1, InetAddress.getLocalHost());

ServerSocket Sınıfı İçin Boş Port Bulma

Giriş
İki yöntem var
1. Rastgele (Ephemeral) port kullanılır. İşletim sistemi boş bir port kullanmayı garanti eder
2. Deneyerek kullanılmayan port bulunur

1. Rastgele (Ephemeral) Port Kullanma
Örnek
Şöyle yaparız. Burada bind() çağrısına 0 değeri veriliyor
ServerSocket serverSocket = new ServerSocket();
serverSocket.setReuseAddress(true);
// Bind to an ephemeral port
serverSocket.bind(new InetSocketAddress(0));
InetSocketAddres localAddress = (InetSocketAddress) serverSocket.getLocalSocketAddress();
Örnek
Şöyle yaparız. Burada sonradan bind() yerine direkt constructor içine 0 değeri veriliyor. spawn() yeni bir thread başlatıyor. uncheckRun() ise fırlatılan exception'ları @SneakThrows gibi yapıyor
 try (ServerSocket socket = new ServerSocket(0) ) {
  int localPort = socket.getLocalPort();
  ...
}
2. Portları Deneyerek Bulma
Bir yazı burada
Örnek
Şöyle yaparız. Bu kodu Spring'in TestSocketUtils sınıfından devşirdim. Rastgele bir port bulmayı 5 kere deniyor
import static org.junit.Assert.fail;

public class TestSocketUtils {
  static final int PORT_RANGE_MIN = 1024;
  static final int PORT_RANGE_MAX = 65535;
  private static final int PORT_RANGE = PORT_RANGE_MAX - PORT_RANGE_MIN + 1;
  private static final int MAX_ATTEMPTS = 5;
  private static final Random random = new Random(System.nanoTime());
  private static final TestSocketUtils INSTANCE = new TestSocketUtils();

  public static int findAvailableTcpPort() {
    return INSTANCE.findAvailableTcpPortInternal();
  }

  int findAvailableTcpPortInternal() {
    int candidatePort;
    int attemptCounter = 0;
    do {
      if (++attemptCounter > MAX_ATTEMPTS) {
        String message = "Could not find an available TCP port";
        fail(message);
      }
      candidatePort = PORT_RANGE_MIN + random.nextInt(PORT_RANGE);
    }
    while (!isPortAvailable(candidatePort));

    return candidatePort;
  }
}
port'u kontrol eden kod şöyle. Burada createServerSocket() çağrısına backlog olarak 1 geçiliyor. Yani sadece 1 client bekleyebilir
boolean isPortAvailable(int port) {
  try {
    ServerSocket serverSocket = ServerSocketFactory.getDefault()
      .createServerSocket(port, 1, InetAddress.getByName("localhost"));
    serverSocket.close();
    return true;
  } catch (Exception ex) {
    return false;
  }
}
Örnek
Bir başka örnek burada. basePort numarasından başlayarak belirtilen sayı kadar boş port bulmaya çalışıyor. Burada hem TCP hem de UDP portlarına bakıyor. Biraz gereksiz olmuş
public static int getAvailablePort(int basePort) {
  return getAvailablePorts(basePort, 1).get(0);
}

public static List<Integer> getAvailablePorts(int basePort, int portCount) {
  List<Integer> availablePorts = new ArrayList<>();
  int port = basePort;
  for (int i = 0; i < portCount; i++) {
    while (!isPortAvailable(port)) {
      port++;
    }
    availablePorts.add(port++);
  }
  return availablePorts;
}

public static boolean isPortAvailable(int port) {
  ServerSocket ss = null;
  DatagramSocket ds = null;
  try {
    ss = new ServerSocket(port);
    ss.setReuseAddress(true);
    ds = new DatagramSocket(port);
    ds.setReuseAddress(true);
    return true;
  } catch (IOException e) {
    return false;
  } finally {
    if (ds != null) {
      ds.close();
    }
    try {
      if (ss != null) {
        ss.close();
      }
    } catch (IOException e) {
     ignore(e);
    }
  }
}


21 Mart 2018 Çarşamba

InetAddress Sınıfı - IPv4 veya IPv6 Adresi

Giriş
Şu satırı dahil ederiz.
import java.net.InetAddress;
Bu sınıf IPv4 veya IPv6 adresini temsil eder. C# dilindeki karşılığı IPAddress sınıfıdır.

InetAddress  vs InetSocketAddress 
Açıklaması şöyle
- An InetAddress corresponds to the Network Layer (Layer 3) and is basically an IP address.
- A InetSocketAddress corresponds to the Transport Layer (Layer 4) and consists of an IP address and a port number.

İstemci Socket
Bu sınıf istemci socket açmak için kullanılır. Şöyle yaparız
int SERVERPORT = 4000;
String SERVER_IP = "192.168.8.112";

InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Socket socket = new Socket(serverAddr, SERVERPORT);      
Sunucu Socket
Bu sınıf sunucu socket açmak için kullanılır. 
Örnek
Şöyle yaparız.
int port = 31_003;
ServerSocket serverSocket = ServerSocketFactory.getDefault()
  .createServerSocket(port, 1, InetAddress.getLocalHost());
getAllByName metodu
İmzası şöyle
public static InetAddress[] getAllByName(String host)
getByName() kesinlikle kullanılmamalı. Bunun yerine getAllByName() kullanılmalı. Açıklaması şöyle
Avoid APIs that convert a hostname to a single IP address:
- java.net.Socket(String,int)
- java.net.InetSocketAddress(String,int)
- java.net.InetAddress.html#getByName(String)
Örnek - İstemci Socket
Şöyle yaparız
Socket doConnect(String hostname, int port) throws IOException {
  IOException exception = null;
  for (InetAddress address : InetAddress.getAllByName(hostname)) {
    try {
      return new Socket(address, port);
    } catch (IOException e) {
      if (exception == null) {
        exception = e;
      } else {
        exception.addSuppressed(e);
      }
    }
  }
  throw exception;
}
veya şöyle yaparız
Socket doConnect(String hostname, int port) throws IOException {
  IOException exception = null;
  for (InetAddress address : InetAddress.getAllByName(hostname)) {
    try {
      Socket s = new Socket();
      s.connect(new InetSocketAddress(address, port));
      return s;
    } catch (IOException e) {
      if (exception == null) {
        exception = e;
      } else {
        exception.addSuppressed(e);
      }
    }
  }
  throw exception;
}
getAddress metodu
Örnek
Şöyle yaparız. Byte dizisi 192,168,1,20 gibi değerler içerir.
byte[] octets = inetAddress().getAddress();
Örnek
Bir ağdaki tüm IP'leri dolaşmak için şöyle yaparız.
byte[] ip = InetAddress.getLocalHost().getAddress(); 

for (int i = 0; i < 255; i++) { 
  ip[3] = (byte)i; 
  InetAddress address = InetAddress.getByAddress(ip); 
  if (address.isReachable(1000))  { 
    System.out.println(address.getHostAddress()+"can be pinged with Name"+
                       InetAddress.getByAddress(ip).getHostName() );
  } 
}
getByAddress metodu
İmzası şöyle
public static InetAddress getByAddress(byte[] addr)
Örnek
Şöyle yaparız.
InetAddress inetAddress = InetAddress.getByAddress(new byte[] {127,0,0,1}));
Örnek
Bu sınıf sunucu socket açmak için kullanılır. Şöyle yaparız.
int port=31003;
ServerSocket socket = 
  new ServerSocket(port,0, InetAddress.getByAddress(new byte[] {127,0,0,1}));
Örnek
Şöyle yaparız.
int broadcast = ...;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
  quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
InetAddress inetAddress = InetAddress.getByAddress(quads);
getByAddress metodu
İmzası şöyle
public static InetAddress getByAddress(String host, byte[] addr)
Örnek ver

getByName metodu
İmzası şöyle
public static InetAddress getByName(String host)
Örnek - IP
IP ile çalışabilir. Şöyle yaparız.
InetAddress inetAddress = InetAddress.getByName("192.168.1.5");
Örnek - Sunucu İSmi
Gerekirse DNS sunucunu kullanır. Şöyle yaparız.
String url = "http://reddit.com";
InetAddress inetAddress = InetAddress.getByName(address);
getCanonicalHostName metodu
foo.example.com gibi bir çıktı verir.

getHostAddress metodu
Şöyle yaparız.
System.out.println("IP = " + inetAddress.getHostAddress());
getHostName metodu
Örnek ver.

getLocalHost metodu
Örnek
Şöyle yaparız. 192.168.1.2 gibi bir IP adresi döner.
InetAddress localIP = InetAddress.getLocalHost();
Aslında şu kodla aynı
InetAddress.getByName("localhost")
getLoopbackAddress metodu
Açıklaması şöyle
To resolve a loopback address, prefer InetAddress.getLoopbackAddress() over hard-coding an IPv4 or IPv6 loopback address with InetAddress.getByName("127.0.0.1") or InetAddress.getByName("::1").
isReachable metodu
Şöyle yaparız. Sanırım verilen adresi Ping'ler.
String ip ="172.20.1.";
if(InetAddress.getByName(host).isReachable(1000)) {...]