자바의 신 28장 - 다른 서버로 데이터를 보내려면 어떻게 하면 되나요?

so2·2021년 7월 26일
1
post-custom-banner

네트워킹

  • 서로 연결하는 것을 의미한다. 사용자-장비, 장비-장비간 데이터를 주고 받는 작업
  • JAVA로 TCP통신을 한다면 JAVA에서 제공하는 API를 사용하면 된다.
  • 애플리케이션 레이어에서 프로그래밍만 하면 트랜스포트 레이어에서의 처리는 자바에서 알아서 처리한다.

Socket클래스

  • TCP 통신을 수행할 때 사용한다
  • 원격에 있는 장비와의 연결 상태를 보관하고 있다
  • 서버에서는 ServerSocket클래스를 사용해 데이터를 받는다

생성자

Socekt() : 소캣 객체만 생성
Socekt(Proxy proxy) : 프록시 관련 설정과 함께 소켓 객체만 생성 
Socekt(SocketImpl impl) : 사용자가 지정한 SocketImpl 객체를 사용해 소켓 객체만 생성 
Socekt(InetAddress address, int port) : 소캣 객체 생성 후            
                                        address와 port를 사용하는 서버에 연결 
Socekt(InetAddress address, int port, InetAddress localAddr, int localPort) 
                          소켓 객체 생성 후 address와 port를 사용하는 서버에 연결하며, 
                          지정한 localAddr와 localPort에 접속 
Socekt(String host, int port) : 소켓 객체 생성 후 host와 port를 사용하는 서버에 연결 
Socekt(String host, int port, InetAddress localAddr, int localPort)
                          소켓 객체 생성 후 host와 port를 사용하는 서버에 연결하며, 
                          지정된 localAddr와 localPort에 접속 
  • 위에 세 개의 생성자를 제외한 나머지 생성자들은 모두 객체 생성과 함께 지정된 서버에 접속한다

ServerSocket클래스

  • 클라이언트 요청이 생기면 Socket객체를 생성한다

생성자

ServerSocket() : 서버 소켓 객체만 생성
ServerSocket(int port) : 지정된 포트를 사용하는 서버 소켓을 생성
		         기본 backlog의 개수는 50ServerSocket(int port, int backlog) : 지정된 포트와 backlog 개수를 가지는 소켓을 생성 
ServerSocket(int port, int backlog, InetAddress) : 
지정된 포트와 backlog 개수를 가지는 소켓을 생성하며, bindAddr에 있는 주소에서의 접근만을 허용

***** backlog : 큐의 개수 
	        ServerSocket객체가 바빠 연결 요청을 처리 못하고 대기시킬 때의 최대 개수
  • 매개 변수가 없는 ServerSocket() 생성자는 별도의 연결 작업을 해야만 대기가 가능하고, 나머지들은 객체가 생성되자 마자 연결을 대기할 수 있는 상태가 된다

메서드

Socket accept() : 새로운 소켓 연결을 기다리고, 연결이 되면 Socket객체를 리턴
void close() : 소켓 연결을 종료 

TCP 소켓 통신

서버 소스

public void startServer(){
  ServerSocket server = null; 
  Socket client = null;
  try{
      // 9999번 포트의 ServerSocket 객체 생성 
      server = new ServerSocket(9999);
      while(true){
          // 원격 호출을 대기하는 상태 
          // 연결이 완료되면 Socket 객체를 리턴해 client 변수에 할당 
          client = server.accept();
          // 데이터를 전달 받기 위한 객체 
          InputStream stream = client.getInputStream();
          BufferedReader in = new BufferedReader(new InputStreamReader(stream));
          String data = null;
          StringBuilder receivedData = new StringBuilder();
          while((data=in.readLine())!=null){
              receivedData.append(data);
          }
          System.out.println("reveive = " + receivedData);
          in.close();
          stream.close();
          // 모든 데이터 처리가 끝난 후 호출 
          client.close();
          if(receivedData!=null && "EXIT".equals(receivedData.toString()))
              break;
      }catch(Exception e){
          e.printStackTrace();
      }finally{
          if(server!=null){
           try{
              // 더 이상 소켓 수신할 필요가 없을 때 호출 
              server.close();
              }catch(Exception e){
                  e.printStackTrace();
          }
       }
     }
  }
}

클라이언트 소스

public void sendSocketSample(){
	for(int loop=0;loop<3;loop++){
    	sendSocketData("I liked java at" + new Date());
    }
    sendSocketData("EXIT");
}

public void sendSocketData(String data){
    Socket socket=null;
    try{
    	// ip와 포트 번호를 매개 변수로 갖는다. 
        // 포트 번호는 서버쪽에서 지정한 포트와 동일해야 한다. 
    	socket = new Socket("127.0.0.1",9999);
        Thread.sleep(1000);
        // 서버에 데이터를 전달하기 위한 객체 생성 
        OuputStream stream = socket.getOuputStream();
        BufferedOutputStream out = new BufferdOutputStream(stream);
        byte[] bytes = data.getBytes();
        out.write(bytes);
        out.close();
    }catch(Exception e){
    	e.printStackTrace();
    }finally{
    	if(socket!=null){
          try{
                  socket.close();
              }catch(Exeption e){
                  e.printStackTrace();
              }
        }
    }
}

UDP 통신

DatagramSocket 클래스

  • 데이터를 주고 받기 위한 클래스

생성자

DatagramSocket() : 소켓 객체 생성 후 사용 가능한 포트로 대기 
DatagramSocket(DatagramSocketImpl impl) : 사용자가 지정한 SocketImpl 객체를 사용해 
 					  소켓 객체만 생성 
DatagramSocket(int port) : 소켓 객체 생성 후 지정된 port로 대기 
DatagramSocket(int port, InetAddress address) : 소켓 객체 생성 후
                                                address와 port를 사용하는 서버에 연결 
DatagramSocket(SocketAddress address) : 소켓 객체 생성 후 address에 지정된 서버로 연결

메소드

void receive(DatagramPacket packet) : 메소드 호출시 요청을 대기하고, 
                                      데이터를 받으면 packet 객체에 데이터 저장 
void send(DatagramPacket packet) : packet 객체에 있는 데이터 전송

DatagramPacket클래스

생성자

DatagramPacket(byte[] buf, int length) : length의 크기의 데이터를 받기 위한 객체 생성
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
				지정된 address와 port로 데이터를 전송하기 위한 객체 생성 
DatagramPacket(byte[] buf, int offset, int lenght) 
			    버퍼의 offset이 할당되어 있는 데이터를 전송하기 위한 객체 생성 
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 
     버퍼의 offset이 할당되어 있고, 지정된 address와 port로 데이터를 전송하기 위한 객체 생성 
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 
       버퍼의 offset이 할당되어 있고, 지정된 소켓 address로 데이터를 전송하기 위한 객체 생성 
DatagramPacket(byte[] buf, int length, SocketAddress address) 
			           지정된 소켓 address로 데이터를 전송하기 위한 객체 생성 
                       
***** buf : 전송되는 데이터 
***** offset : 전송되는 byte 배열의 첫 위치 
***** length : 데이터의 크기  

메소드

byte[] getData() : 전송받은 데이터 리턴 
int getLength() : 전송받은 데이터의 길이 리턴 

서버 소스

public void startServer(){
  DatagramSocket server = null; 
  try{
      server=new DatagramSocket(9999);
      int bufferLength=256;
      byte[] buffer = new byte[bufferLength];
      // 데이터를 받기위한 객체를 생성 
      DatagramPacket packet = new DatagramPacket(buffer, bufferLength);
      while(true){
      	  // 데이터를 받기 위해 대기하고 있다가, 데이터가 넘어오면 packet객체에 담는다
          server.receive(packet);
          int dataLength=packet.getLength();
          // byte배열로 되어 있는 데이터 String 문자열로 변경
          String data = new String(packet.getData(),0,dataLength);
          System.out.println("reveive = " + data);
          if(data.equals("EXIT"))
              break;
      }
  }catch(Exception e){
      e.printStackTrace();
  }finally{
      if(server!=null){
          try{
              server.close()
          }catch(Exception e){
          e.printStackTrace();
      	  }
      }
  }
}

클라이언트 소스

public void sendDatagramSample(){
    for(int loop=0;loop<3;loop++){
      sendDatagramData("I liked UPD " + new Date());
    }
    sendDatagramData("EXIT");
}
public void sendDatagramData(String data){
  try{
    	DatagramSocket client = new DatagramSocket();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        byte[] buffer = data.getBytes();
        // 데이터 전송을 위한 객체 생성 
        DatagramPacket packet = 
        	new DatagramPacket(buffer, 0, buffer.length, address, 9999);
        // 데이터 전송 
        client.send(packet);
        client.close();
        Thread.sleep(1000);
    }catch(Exception e){
    	e.printStackTrace();
    }
}
post-custom-banner

0개의 댓글