이롭게 현명하게

[JAVA] 자바 서버생성 단계 본문

JAVA

[JAVA] 자바 서버생성 단계

dev_y.h 2023. 1. 18. 18:59
728x90
반응형


 

목차

1. ServerSocket 객체 생성

2. accept() 메소드 호출

3. 소켓으로부터 스트림 객체를 얻는다.

4. 상호 대화 단계

5. 종료

 

날짜 서버

날짜 클라이언트

실행방법


 


[1. ServerSocket 객체 생성]

ServerSocket server = new ServerSocket(portNumber,queueLength);

ServerSocket 생성자를 호출하면 생성자의 매개변수에는 portNumber 와 queueLength를 가진 소켓을 생성한다.

queueLength : 서버에 연결되기를 기다리는 클라이언트의 최대 개수

portNumber : 포트번호로 클라이언트가 서버 컴퓨터에서 서버 애플리케이션을 찾기 위해 필요.

각 클라이언트는 이 포트번호를사용하여 서버에 연결을 요청한다.

 


[2. accept() 메소드 호출]

서버는 클라이언트가 연결을 시도하기를 기다린다. 이 때 ServerSocket의 메소드인 accept()를 호출한다.

Socket clientSocket = server.accept();

 

accept()메소드는 클라이언트와 연결이 되면 새로운 Socket 객체를 생성하여 반환한다.

이 새로운 Socket 객체를 통해 서버는 클라이언트와 상호작용할 수 있다.

이전 단계에서의 portNumber에 연결된 소켓은 다른 클라이언트의 연결을 위하여 그냥 두어야한다.

 


[3. 소켓으로부터 스트림 객체를 얻는다.]

서버가 클라이언트와 바이트를 주고 받기 위해 InputStream과 OutputStream객체를 필요로한다.

서버는 OuputStream을 통해 클라이언트에게 정보를 전송한다.

클라이언트로부터의 정보는 InputStream을 통해 얻는다.

Socket의 getOuputStream()과 getInputStream()메소드를 사용한다.

InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();

write()와 read()를 사용하여 읽고 쓸 수 있다.

 


[4. 상호 대화 단계]

서버와 클라이언트는 스트리을 이용하여 상호 대화한다. 서버와 클라이언트 사이에는 미리 약속된 프로토콜이 있어야한다.

 


[5. 종료]

서버와 클라이언트 사이에 전송이 끝나면 서버가 close() 메소드를 호출하여 스트림과 소켓을 닫아 종료시킨다.

 


[날짜 서버]

 

DateServer.java

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

public class DateServer {

	public static void main(String[] args) throws IOException {
		ServerSocket ss = new ServerSocket(9100);//포트 9100번으로 서버 소켓을 만든다.
		try {
			while (true) {
				Socket socket = ss.accept();//클라이언트의 연결을 기다린다.
				try {
					PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
					out.println(new Date().toString());//날짜를 클라이언트로 보낸다.
				} finally {
					socket.close();
				}
			}
		} finally {
			ss.close();
		}
		
	}

}

위 소스를 실행하면 서버는 콘솔 창에는 아무것도 뜨지않고 무한루프를 돌게된다.

만약 실행을 했을 때 Exception in thread "main" java.net.BindException: Address already in use: bind 와 같은 오류가 나타난다면 서버를 작성할 때는 다른 서비스가 사용하지 않는 포트 번호를 선택해야하기 때문에 port 번호를 바꾸어주면 된다.

 

서버 프로그램은 먼저 특정한 포트에서 요청을 기다리기 위해 새로운 Serversocket을 만듦으로써 시작한다.

ServerSocket ss = new ServerSocket(9100);

ServerSocket : 클라이언트-서버 소켓 연결에서 서버 측의 구현을 제공하는 클래스

포트를 연결하지 못하면 예외를 발생시킨다.

 

서버가 성공적으로 포트에 연결되면 ServerSocket 객체는 생성되고 서버는 클라이언트로 부터의 요청을 기다린다.

Socket socket = ss.accept();

accept()메소드는 클라이언트가 시작되어 호스트로 서비스를 요청할 때 까지 기다린다.

연결이 요청된 후 접속에 성공한다면 accept() 메소드는 새로운 포트와 연결된 Socket객체를 반환한다.

이 새로운 Socket을 통해 서버는 클라이언트와 계속 연결 요청을 기다릴 수 있다.

서버가 클라이언트와 성공적으로 연결을 설정한 다음에 서버는 클라이언트와 스트림을 이용하여 통신한다.

 


[날짜 클라이언트]

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;

public class DateClient {

	public static void main(String[] args) throws IOException {
		Socket s = new Socket("localhost",9100);//포트번호9100번으로 연결을 시도한다.
		BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream()));//소켓으로부터 스트림을 얻는다.
		String res = input.readLine();
		System.out.println(res);
		
		System.exit(0);
		
	}

}

 


[실행방법]

이클립스를 사용하고있어 서버를 먼저 실행한 후에 클라이언트 소스를 실행한다.

1. 서버소스를 선택한 상태에서 마우스 오른쪽 버튼을 클릭 [Run As] ->[Java Application] 실행

2. 클라이언트 소스를 선택한 상태에서 마우슨 오른쪽 버튼 클릭 [Run As] ->[Java Application] 실행

3. 성공

 

더보기

명령어로 실행하기

C> java DateServer

C> java DateClient

 

서버가 미리 실행되고 있어야 미리 정해진 포트에서 클라이언트의 접속요청을 기다릴 수 있다.

그래서 클라이언트 프로그램이 처음으로 하는 것은 호스트 이름과 포트를 통해 수행되는 서버에 접속한다.

 

Socket s = new Socket("localhost",9100);

소켓을 만들 때 DateClient는 호스트 이름으로 "localhost"를 사용한다.

이것은 현재 실행되는 프로그램의 로컬 호스트의 이름이다.

만약 네트워크 사의 특정 컴퓨터에서 서버가 실행되고 있다면 특정 컴퓨터의 이름이어도 된다.

포트 번호 9100은 서버 컴퓨터에 있는 포트번호로 DateServer가 접속 요청을 기다리고있는 포트다.

이후에 클라이언트는 Socket()이 반환하는 소켓에서 입력 스트림을 추출한 후에,입력 스트림에서 한줄의 문자열을 읽어서 화면에 출력한다.

 


서버는 하나의 클라이언트에게만 제공되는 것이 아닌 동시에 여러 클라이언트에게 서비스를 제공해야한다.

여러 클라이언트에게 서비스를 제공하기 위해서는 서버의 구조를 조금씩 변경해야한다. 그러기 위해서는 각 클라이언트마다 스레드를 하나씩 생성하여 동시에 여러 클라이언트들에게 서비스를 제공하는 서버를 만들 수 있다.

while(true){
	//연결 요청을 수락한다.;
    //클라이언트를 대응하는 스레드를 만든다.;
}

서버에 연결요청이 오면 연결 요청을 수락하고 새로운 스레드 서버 객체를 생성한다.

스레드 객체에 accept() 메소드가 반환하는 소켓을 전달한 후에 스레드의 수행을 시작하고 서버는 다시 새로운 다른 요청이 오기를 기다린다. 이때 스레드 객체는 자신에게 전달된 소켓을 통해 클라이언트와 통신한다.

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

728x90
반응형
Comments