728x90
반응형

Java에서의 Socket

Java에서는 socket class가 있어서 지원해준다.

  • java.net.Socket

    • client side의 TCP operation을 진행하는 기본적인 class
    • 밑에 함수들은 remote socket으로 connection을 open하는 함수이다
    • 기본 Constructor (생성자들) -> 여기서 host와 port는 remote(서버)의 주소와 portnumber이다. 
    public Socket(String host, int port) throws UnknownHostException,IOException
    public Socket(InetAddress host, int port) throws IOException
    
    try{
    	Socket toOReilly = new Socket("www.oreilly.com",80);
    } catch(UnknownHostException ex){
    	System.err.println(ex);
    } catch(IOException ex){
    	System.err.println(ex);
    }
  • remote와 local을 나누어서 local interface 어떤 것을 connect할지 정할 수도 있다.
public Socket(String host, int port, InetAddress interface, int localPort) throws UnknownHostException,IOException

그럼 위의 경우에는 remote만 적어주는데 local은 어떻게 되는 것일까?

→ OS에서 그냥 자동으로 선택해준다

 

또한, Socket을 만들고 바로 connect하는 것이 아니라, 만들고 나중에 connect할 수 도 있다.

public Socket()
public void connect(SocketAddress endpoint, int timeout) throws IOException

 

  • SocketAddress Class
    • connection endpoint ( remote host )를 나타내는 것을 도와주는 클래스
    • abstract class이고 생성자밖에 없다
    • socket connection정보(IP 주소, port number)를 제공하는 저장소 느낌이다
    • connect 함수를 사용할 수도 있다. 
    • Getter method
public SocketAddress getRemoteSocketAddress()
public SocketAddress getLocalSocketAddress()

  • InetSocketAddress Class
    • SocketAddress의 Subclass

 

Socket을 통해서 정보를 읽어보자

  • InputStream in = socket.getInputStream();

Socket을 통해서 서버에 써보자

  • OutputStream out = socket.getOutputStream();

 

예시 -> 사전

  • dict라는 TCP protocol에 port 2628로 "DEFINE eng-lat gold" 라고 request를 보내면 server는 gold의 의미를 English-to-latin 사전으로 definition을 보내준다.
package Socket;

import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;

public class DictClient3 {

    public static void main(String[] args){

        String host = "dict.org";
        try{
            Socket soc = new Socket(host,2628);
            OutputStream out = soc.getOutputStream();
            Writer writer = new OutputStreamWriter(out,"UTF-8");
            writer = new BufferedWriter(writer);
            InputStream in = soc.getInputStream();
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(in,"UTF-8"));
            String request = "DEFINE fd-eng-lat gold";
            writer.write(request);
            writer.flush();
            soc.shutdownOutput();

            for(String line = reader.readLine();line!=null;line=reader.readLine()){
                System.out.println(line);
            }
            soc.close();
        } catch (UnknownHostException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 

 

Socket에 대한 정보 알아오기

Closed or Connected

  • isClosed() 함수는 socket이 닫혀있으면 true를 리턴하고, open되어 있으면 false를 리턴한다.
  • isConnected() 함수는 한번이라도 remote host와 연결되었다면 true를 리턴한다.
  • 만약 socket이 한번도 연결된 적이 없다면 isClosed() 함수는 open되어있지 않더라도 false를 return하게 된다. 
  • 따라서 socket connection이 제대로 open되어있는지 확인하려면 아래와 같이 확인해야 한다.
    • socket.isConnected() && !socket.isClosed()
728x90
반응형

'백엔드 > Network Programming' 카테고리의 다른 글

Non-blocking I/O in Java  (0) 2022.12.12
Socket Programming(3) - Socket for Server  (0) 2022.11.21
Socket Programming(1) - socket이란?  (0) 2022.11.13
URL and URI's key  (2) 2022.10.15
Internet protocols and layers  (2) 2022.09.09
728x90
반응형

 

Socket이란?

소켓을 들으면 일반적으로 전구의 소켓을 떠올릴 것이다. 그리고 컴퓨터에서 말하는 소켓은 전구의 소켓과 비슷하게 연결하는 통로라고 생각하면 된다. 사용자 즉, host가 2명이 있다고 생각해보자. Host가 서로 데이터를 주고 받는다고 생각해보자. 각각의 데이터는 단계별로 통과하여 데이터를 전달하게 되는데, 이 단계는 5가지가 있다. Application, Transport, Network, Link, Physical layer이다. 여기서 Application은 순수 software라고 생각하면 되고, Transport부터 Physical layer까지는 OS에 구현이 되어 있다. (Link layer와 Physical Layer는 NIC에도 있다.)

데이터 통신을 위해서는 먼저, 송신자의 Application에서 Socket이라는 문을 통하여 아래 layer들로 전달되고 수신자도 아래에서부터 데이터가 올라오고, Socket 문을 거쳐서 Application에 데이터가 도달하게 된다. 프로세스가 데이터를 보내거나 받기 위해서는 반드시 소켓을 열어 소켓에 데이터를 쓰거나 읽어야 한다. 

Multiplexing / demultiplexing

Multiplexing과 demultiplexing은 transport layer에서 일어난다. 서로 반대되는 개념인데, multiplexing이 여러 데이터를 한 통로에 넣어서 섞어버리는 것이라면 demultiplexing은 한 통로에서 온 것을 여러 갈래 중 해당하는 곳으로 보내는 것을 의미한다.
우리가 인터넷 호스트에서 demultiplexing이라고 한다면 packet들이 도착했을때, packet들이 어떤 process로 가야되는지 보내는 것을 demultiplexing이라고 한다. Sender에서 multiplexing은 여러 개의 socket에서 오는 data를 handling하는 것을 의미한다. 즉, process마다 socket이 하나 있다고 생각하면 된다. physical layer에서 link, network layer까지는 같이 오다가 transport layer에서 어떤 socket으로 가는지 결정해준다.

어떻게 demultiplexing이 작동할까

 Host는 IP layer(Network Layer)에서는 datagram을 전달받는다. 각각의 datagram은 source와 destination IP address를 가지고 있다. 각 datagram은 하나의 segment를 들고온다. 각 segment는 source와 destination의 port number를 가지고 있다. 그럼 host는 port number와 IP 주소를 이용해서 segment를 적절한 소켓에 데이터를 올려보내는 것이다.

TCP socket은 4가지 정보로 identify된다. Source의 IP주소, Soure의 port number, 목적지의 IP 주소, 목적지의 port number이다. 그럼 서버는 동시에 여러개의 TCP socket을 지원해야 된다. 각각의 socket은 각기 다른 socket으로 연결되는 것이다. socket은 port number에 binding되어야 하고, socket에 port number가 할당되어야만 socket의 기능을 할 수 있다. 위에서 볼 수 있듯이 16bit를 socket number로 사용할 수 있다. 이 중에서 0~1023은 잘 알려진 port로 임의로 사용할 수 없고(ex. 웹 서버:80포트) 임의로 사용할 수 있는 것은 49152~65535 번들이다. 

 

하나의 프로세스는 같은 프로토콜, 같은 IP 주소, 같은 port number를 가지는 소켓을 여러 개 만들 수 있기 때문에, 하나의 프로세스는 하나의 port만으로도 여러 호스트에 있는 프로세스의 요청을 처리할 수 있다. (게임 서버에서 동시 접속자 수가 엄청나게 많을 수 있는 이유도 동일하다) 그래서 서버의 경우는 보통 하나의 포트만 할당받고, 하나의 포트로 여러 개의 소켓을 열게된다. 

 

예시

 

 

위의 그림에서 모두 destination IP 주소는 B이고 port number는 80이다. 여기서 demultiplexing되어 다른 socket으로 들어간다.

 

Port number는 네트워크 상에서 통신하기 위해서 호스트 내부적으로 프로세스가 할당 받아야하는 고유한 숫자이다. 같은 Host 내에서 서로 다른 프로세스가 같은 Port number를 가질 수는 없다. 

728x90
반응형

'백엔드 > Network Programming' 카테고리의 다른 글

Non-blocking I/O in Java  (0) 2022.12.12
Socket Programming(3) - Socket for Server  (0) 2022.11.21
Socket Programming(2) - Socket for Client  (0) 2022.11.13
URL and URI's key  (2) 2022.10.15
Internet protocols and layers  (2) 2022.09.09

+ Recent posts