프로그램 정보
프로그램 개요 : JAVA 소켓 통신을 이용한 1:1 채팅 프로그램 개발
프로그램 언어 : JAVA
프로그램 기능 :
- 채팅 클라이언트 개발
- 채팅 서버 개발
프로그램 코드 : https://github.com/smkim9202/MiniProject/tree/main/chatPrj
MiniProject/chatPrj at main · smkim9202/MiniProject
작은 실습 예제들. Contribute to smkim9202/MiniProject development by creating an account on GitHub.
github.com
JAVA 소켓 통신 학습 내용
자바 네트워크
TCP/IP
- TCP
- TCP(Transmission Control Protocal) 두 시스템 간에 신뢰성 있는 데이터의 전송을 권장하는 프로토콜
- 100개의 정보를 보내면 100개가 도달해야한다는 것을 보장하는 규약
- e-mail, FTP, 웹(HTTP) 등이 TCP에서 동작하는 응용프로그램
- IP
- IP(Internet Protocol) 패킷 교환 네트워크에서 송신 호스트와 수신 호스트가 데이터를 주고 받는 것을 관장하는 프로토콜
- TCP보다 하위 레벨 프로토콜
- 주소를 보고 찾아 갈 수 있게 해주는 프로토콜
- IP 주소
- 네트워크 상에서 유일하게 식별 될 수 있는 컴퓨터 주소(4개의 숫자가 '.'으로 연결 되어 있음 => 192.156.11.15)
- 숫자로 된 주소는 기억하기 어려우므로 문자열로 구성된 도메인 이름으로 바꿔 사용(www.nave.com)
- DNS(Domain Name Server) => 문자열로 구성된 도메인 이름을 숫자로 구성 된 IP 주소로 자동 변환
- 현재는 32비트의 IP 버전 4(IPv4) 사용 중이지만 주소 고갈로 인해 128비트의 IP 버전 6(IPv6)이 점점 사용되는 추세
- 네트워크 상의 컴퓨터 또는 시스템을 식별하는 주소
- PORT
- 컴퓨터가 하나 이상의 역할을 하기 위해 포트를 열어서 사용(web 80, DB 1500 ....)
- 통신하는 프로그램 간에 가상의 연결단인 포트 생성 => 포트 번호를 이용하여 통신할 응용프로그램 식별
- 모든 응용프로그램은 하나 이상의 포트 생성 가능 => 포트를 이용하여 상대방 응용프로그램과 데이터 교환
- 잘 알려진 포트(well-know ports)로는 0~1023 사이의 포트 번호가 있음 => 텔넷 23, HTTP 80, FTP 21
- 개발자는 잘 알려진 포트 번호는 사용하지 않는 것이 좋음(충돌 가능성 있기 때문)
- URL을 이용한 웹 프로그래밍
- URL(Uniform Resource Locator)은 인터넷 상의 리소스에 대한 주소
- URL 구조
- 프로토콜 식별자(protocol identifier)://자원 이름(resource name)
- http://www.naver.com/
- 자원 이름(resource name)
- 사용되는 프로토콜에 따라서 그 구성이 달라짐
- http:호스트이름/파일이름:포트번호(8080)
- https:호스트이름/파일이름:포트번호(443)
- 사용되는 프로토콜에 따라서 그 구성이 달라짐
자바의 URL 클래스
- java.net 패키지에 포함
- 웹 상의 자원을 지정하는 URL을 나타냄
URL 객체
- URL(String spec) : 문자열이 지정하는 자원에 대한 URL 객체를 생성
- URL(String protocol, String host, int port, String file) : 프로토콜 식별자, 호스트 주소, 포트 번호, 파일 이름이 지정하는 자원에 대한 URL 객체 생성
- URL(String protocol, String host, String file) : 프로토콜 식별자, 호스트 주소, 파일 이름이 지정하는 자원에 대한 URL 객체 생성
- URL(URL context, String spec) : URL 객체 context에 대한 상대 경로가 지정하는 자원에 대한 URL 객체 생성
자바의 URL 클래스의 주요 메소드
- Object getContent() : URL의 컨텐트를 반환
- String getFile() : URL 주소의 파일 이름 반환
- String getHost() : URL 주소의 호스트 이름 반환
- String getPath() : URL 주소의 경로 부분 반환
- int getPort() : URL 주소의 포트 번호 반환
- int getLocalPort() : 소켓이 연결된 로컬 포트 번호 반환
- int getPort() : 소켓이 연결한 서버의 포트 번호 반환
- inputStream openStream() : URL에 대해 연결을 설정하고 이 연결로부터 입력을 받을 수 있는 InputStream 객체 반환
- URLConnection openConnection() : URL 주소의 원격 객체에 접속한 뒤 통신 할 수 있는 URLConnection 객체 리턴
자바의 URL 객체 생성 방법
- 절대 경로로 URL 객체 생성
- URL homePage = new URL("http://news.hankooki.com");
- 상대 경로로 URL 객체 생성 : 잘못된 주소의 URL 입력시 MalformedURLException 예외 발생
- URL opinion = new URL(homePage, "opinion/editorial.htm");
- URL 객체에서 데이터 읽기
- openStream() 메소드로 스트림 생성해서 URL 객체가 가리키는 주소에서 데이터를 가져옴
- openStream()이 리턴하는 InputStream 객체를 이용하여 일반 스트림 입력을 수행
URL 객체 예제
package natwork;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class URLRead {
public static void main(String[] args) {
try {
//네트워크 세계
URL url = new URL("https://www.naver.com/");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
//자바의 세계
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
URLConnection 클래스
- 주어진 원격지의 주소 URL에 네트워크 접속 후 데이터를 보내거나 받을 수 있도록 하는 기능
URLConnection 클래스의 주요 메소드
- abstract void connect() : URL에 의해 참조되는 외부 리소스와 통신 연결 설정
- Object getContent() : URL 연결에서 컨텐트를 가져옴
- String getContentEncoding() : 컨텐트 인코딩 필드를 반환
- int getContentLength() : 컨텐트 길이 필드 반환
- String getContentType() : 컨텐트 타입 필드 반환
- boolean getDoInput() : URLConnection 객체의 doInput 필드 값 반환
- boolean getDoOutput() : URLConnection 객체의 doOutput 필드 값 반환
- InputStream getInputStream() : 설정된 연결에서 데이터를 읽을 입력 스트림 반환
- OuputStream getOutputStream() : 설정된 연결로 데이터를 출력할 출력 스트림 반환
- URL getURL() : URLConnection 객체의 URL 필드 값 반환
- void setDoInput(boolean doInput) : URLConnection 객체의 doInput 필드 값 설정
- void setDoOutput(boolan doOutput) : URLConnection 객체의 doOutput 필드 값 설정
URL 객체 생성 방법
- URL.openConnection() 이용
URL aURL = new URL("https://www.naver.com/");
URLConnection uc = aURL.openConnection(); // 원격지와 연결한다.
- URLConnection 생성자 이용 : 연결하기 전 여러가지 인자들과 요청과 관련된 속성들 설정 가능
URL aURL = new URL("https://www.naver.com/");
URLConnection uc = new URLConnection(aURL);
uc.connect(); //원격지와 연결한다.
URLConnection을 이용하여 원격지로 데이터 보내기
- URLConnection 객체에서 데이터 쓰기
- 웹 서버에 데이터를 요청하여 읽어올 때 주로 HTTP GET 사용
- 웹 서버에 데이터를 요청 할 때 같이 처리 될 데이터를 보낼 때 HTTP POST 사용
- URLConnection 객체는 HTTP POST 방식으로 서버에 데이터 전송
HTTP POST 사례
- 회원가입시 성과 이름을 입력하는 필드가 폼(form)
- 필드에 데이터를 입력한 후 전송 버튼을 누르면 웹 서버로 데이터를 전송해야 하는데 이 데이터를 보내는 방법
웹 서버에 데이터를 보내기 위해서 필요한 단계
- URL 생성
- URL 객체에서 URLConnection 객체를 얻어온다.
- setDoOutput() 메소드로 doOuput 필드를 true로 설정
- connect() 메소드로 연결 설정
- 연결에서 출력 스트림을 얻어 온다.
- 출력 스트림에 데이터를 출력
- 출력 스트림을 닫는다.
package natwork;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class URLConnectionWriter {
public static void main(String[] args) {
try {
//POST가 가능한 사이트 URL 객체 생성
URL aURL = new URL("");
//URL 객체에서 URLConnection 객체 생성
URLConnection uc = aURL.openConnection();
//출력 모드 설정
uc.setDoOutput(true);
//출력 스트림 설정
OutputStreamWriter out = new OutputStreamWriter(uc.getOutputStream());
//서버에 데이터 보내기
out.write("fname=Kitea&lname=Hwang");
out.close();
//입력 스트림 생성
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null) //한행 씩 읽음
System.out.println(inputLine);
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
소켓 프로그래밍
소켓(socket)
- 네트워크 상에서 수행되는 두 프로그램 간의 양방향 통신 링크의 한쪽 끝 단을 의미
- 특정 포트 번호와 연결되어 있음(TCP에서 데이터를 보낼 응용프로그램을 식별 할 수 있음)
- 자바에서의 데이터 통신 시 소켓 사용
- 소켓 종류 : 서버 소켓, 클라이언트 소켓

소켓을 이용한 서버 클라인트 통신 프로그램의 구조
클라이언트 소켓 =접속=> 서버 소켓 => 소켓 생성 => 소켓과 클라이언트끼리 소통
- 클라이언트 소켓이 지정된 IP주소와 포트번호에 맞는 서버 소켓에 접속
- 서버 접속 시 소켓이 생성
- 소켓과 클라이언트과 소통
Socket 클래스
- 클라이언트 소켓에 사용되는 클래스
- java.net 패키지에 포함
- 주요 생성자
- Socket(IntAddress address, int port) : 소켓을 생성하여 지정된 IP 주소와 포트 번호에 연결
- Socket(String host, int port) : 소켓을 생성하여 지정된 호스트와 포트 번호에 연결. 호스트 이름이 null인 경우는 루프백(loopback) 주소로 가정
- 주요 메소드
- void close() : 소켓을 닫음
- void connect(SocketAdress endpoint) : 소켓을 서버에 연결
- InetAddress getInetAddress()
- InputStream getInputStream() : 소켓에 대한 입력 스트림 반환
- InetAddress getLocalAddress()
- int getLocalPort()
- int getPort()
- OutputStream getOutputStream() : 소켓에 대한 출력 스트림 반환
소켓 생성, 서버 접속, 입출력 스트림 생성
- 클라이언트 소켓 생성 및 서버에 접속 : Socket 객체가 생성되면 곧 바로 IP주소로 자동 접속
- Socket clientSocket = new Socket("IP", 포트번호);
2. 네트워크 입출력 스트림 생성 : 일반 스트림을 입출력 하는 방식과 동일
- BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
3. 서버로 데이터 전송 : flush()를 호출하면 스트림 속에 데이터를 남기지 않고 모두 전송
- out.write("hello"+"\n");
out.flush();
4. 서버로부터 데이터 수신
- int x = in.read(); //서버로부터 한 개의 문자 수신
String line = in.readline(); //서버로부터 한 행의 문자열 수신
5. 네트워크 접속 종료
- clientSocket.close();
ServerSocket 클래스, 서버 소켓
- 서버 소켓에 사용되는 클래스
- java.net 패키지에 포함
- 주요 생성자
- ServerSocket(int port) : 소켓을 생성하여 지정된 포트 번호에 연결
- 주요 메소드
- Socket accept() : 연결 요청을 기다리다 연결 요청이 들어오면 수락하고 새 Socket 객체를 반환
- void close()
- InetAddress getInetAddress()
- int getLocalPort()
- boolean isBound()
- boolean isClosed()
- void setSoTimeout(int timeout)
클라이언트와 서버
클라이언트와 서버 연결
- 서버는 서버 소켓으로 들어오는 연결 요청을 기다림 (서버 - 포트 - listen)
- 클라이언트가 서버에 연결 요청(클라이언트 - 포트 ==연결요청==> listen - 포트 - 서버)
- 서버가 연결 요청 수락, 새로운 소켓 생성 후 클라이언트와 연결(새로운 소켓 - 서버포트 <==연결==> 클라이언트포트)
서버소켓 생성, 클라이언트 접속, 입출력 스트림 생성
1. 서버 소켓 생성 : 이미 사용 중인 포트 번호 지정 시 오류 발생 주의
- ServerSocket serverSocket = new ServerSocket(포트번호);
2. 클라이언트로부터 접속 기다림 : accept() 메소드는 연결 요청이 오면 새로운 Socket 객체 반환
- 서버에서 클라이언트와의 데이터 통신은 새로 만들어진 Socket 객체를 통해 이루어짐
- Socket socket = serverSocket.accept();
3. 네트워크 입출력 스트림 생성 : 일반 스트림을 입출력 하는 방식과 동일하게 네트워크 데이터 입출력
- accept() 메소드에서 얻은 Socket 객체의 getInputStream()과 getOutputStream()메소드를 이용하여 데이터 스트림 생성
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
클라이언트로 데이터 송수신
1. 클라이언트로부터 데이터 수신
- int x = in.read(); // 클라이언트로부터 한 개의 문자 수신
- String line = in.readline(); //클라이언트로부터 한 행의 문자열 수신
2. 클라이언트로 데이터 전송
- out.write("Hi"+"\n")
- out.flush() //스트림 속에 데이터 남기지 말고 모두 전송
3. 네트워크 접속 종료
- socket.close();
4. 서버 응용프로그램 종료 : 더 이상 클라이언트의 접속을 받지 않고 서버 응용 프로그램을 종료하고자 하는 경우
- serverSocket.close();
소켓을 이용한 클라이언트/서버 채팅
간단한 채팅 프로그램 예제(1:1 채팅 하는 간단한 예제)
기능정리
- 서버와 클라이언트 간의 메시지 구분을 위해 서버는 메시지 앞에 "서버>"를 접두어로 붙여 메시지를 전송한다.
- 서버와 클라이언트가 번갈아 가면서 메시지 전송 및 수신
- 클라이언트가 bye를 보내면 프로그램 종료
서버 프로그램
1. 서버 소켓 생성
- 시스템에서 사용되지 않는 포트 번호로 서버 소켓 생성
- ServerSocket listener = new ServerSocket(포트번호);
2. 클라이언트 요청 대기
- 클라이언트가 연결 요청이 올 때까지 소켓 기다림
- 해당 포트 번호로 연결 요청이 오면 연결을 수락하고 새로운 소켓을 생성 후 새 소켓으로 클라이언트와 통신
- 새로운 소켓의 포트 번호는 자동으로 할당
3. 클라이언트와 통신을 위한 입출력 스트림 생성
- 스트림을 생성하여 클라이언트와 데이터 송수신
- 데이터의 종류에 따라 바이트 스트림 또는 문자 스트림을 생성
- 채팅과 같이 문자열을 송수신하는 경우는 문자 스트림 사용
- 효율적인 입출력을 위하여 버퍼 스트림(Buffered Stream) 사용
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
4. 클라이언트의 데이터 수신
- 스트림 생성 이후는 데이터 입력 받는 방법과 동일
- 클라이언트에서 한 행의 문자열을 보내올 때까지 기다림
- String inputMessage = in.readLine();
5. 클라이언트의 데이터 송신
- 스트림 생성 이후는 일반 데이터를 출력하는 방법과 동일
- 콘솔에서 입력 받은 문자열을 클라이언트로 송신
- flush() 메소드로 스트림의 모든 데이터를 클라이언트로 송신
- String outputMessage = stin.readLine();
out.write("서버>" + outputMessage + "\n");
out.flush();
6.연결 종료
- 데이터 송수신이 끝나면 소켓 닫음
- 소켓을 닫으면 소켓의 입출력 스트림도 같이 닫힘
- 서버 소켓을 닫으면 클라이언트 연결 요청 받을 수 없음
- socket.close();
listener.close();
클라이언트 프로그램
1. 연결 요청 : 소켓생성(서버의 호스트 주소, 서버가 연결 요청을 모니터링하는 포트 번호로 소켓 생성)
- socket = new Socket("localhost", 포트번호); // 동일한 시스템에서 동작하기 때문에 IP주소는 localhost로 지정
2. 클라이언트와 통신을 위한 입출력 스트림 생성
- 스트림을 생성하여 서버와 데이터 송수신
- 데이터 종류에 따라 바이트 스트림 또는 문자 스트림 사용
- 채팅과 같이 문자열을 송수신하는 경우는 문자 스트림 사용
- 효율적 입출력을 위하여 버퍼 스트림(Buffered Stream) 사용
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
3. 서버에 데이터 송신
- 스트림 생성 이후는 데이터 출력 방법과 동일
- 콘솔에서 입력 받은 문자열을 서버로 송신
- flush() 메소드로 스트림의 모든 데이터를 서버로 송신
- String outputMessage = stin.readLine();
out.write("클라이언트>"+outputMessage+"\n");
out.flush();
4. 클라이언트의 데이터 수신
- 스트림 생성 이후는 데이터 입력 방법과 동일
- 서버에서 한 행의 문자열을 보내 올 때까지 기다림
- String inputMessage = in.readLine();
5. 연결 종료
- 데이터의 송수신이 끝나면 소켓 닫아야 함
- 소켓을 닫으면 소켓의 입출력 스트림도 같이 닫힘
- socket.close();
간단한 1:1채팅 프로그램 예제 코드
서버
package chat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ServerEx {
public static void main(String[] args) {
ServerSocket server = null;
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
Scanner sc = new Scanner(System.in);
try {
server = new ServerSocket(9999);
System.out.println("서버시작 : 연결 대기중....");
socket = server.accept();
System.out.println("클라이언트와 연결 됨");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while(true) {
String inMsg = in.readLine();
if(inMsg.equalsIgnoreCase("bye")) {
System.out.println("클라이언트가 나감");
break;
}
//정상 메시지인 경우
System.out.println("클라이언트 : "+ inMsg);
System.out.println("보내기 >>");
String outMsg = sc.nextLine();
out.write(outMsg + "\n");
out.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
sc.close();
out.close();
in.close();
socket.close();
server.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
클라이언트
package chat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientEx {
public static void main(String[] args) {
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
Scanner sc = new Scanner(System.in);
try {
socket = new Socket("localhost", 9999);
System.out.println("서버에 연결 됨");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while(true) {
System.out.println("보내기>>");
String outMsg = sc.nextLine();
if(outMsg.equalsIgnoreCase("bye")) {
out.write(outMsg + "\n");
out.flush();
System.out.println("접속 종료!!!");
break;
}
//정상 메시지인 경우
out.write(outMsg + "\n");
out.flush();
String inMsg = in.readLine();
System.out.println("서버>>" + inMsg);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
sc.close();
out.close();
in.close();
socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
'프로젝트 > mini project' 카테고리의 다른 글
[JSP MVC1 : GoGoTaiwan] JSP를 이용한 MVC1 패턴의 웹사이트 (0) | 2021.12.04 |
---|---|
[Frontend : MainPageExample] 웹사이트 Main 페이지 (0) | 2021.10.30 |
[Frontend : DropDownExample] 드롭다운형식 메뉴바 (0) | 2021.10.18 |
[Frontend : CodingStudy] Frontend 웹페이지 + 깃헙 웹 호스팅 (0) | 2021.01.04 |
프로그램 정보
프로그램 개요 : JAVA 소켓 통신을 이용한 1:1 채팅 프로그램 개발
프로그램 언어 : JAVA
프로그램 기능 :
- 채팅 클라이언트 개발
- 채팅 서버 개발
프로그램 코드 : https://github.com/smkim9202/MiniProject/tree/main/chatPrj
MiniProject/chatPrj at main · smkim9202/MiniProject
작은 실습 예제들. Contribute to smkim9202/MiniProject development by creating an account on GitHub.
github.com
JAVA 소켓 통신 학습 내용
자바 네트워크
TCP/IP
- TCP
- TCP(Transmission Control Protocal) 두 시스템 간에 신뢰성 있는 데이터의 전송을 권장하는 프로토콜
- 100개의 정보를 보내면 100개가 도달해야한다는 것을 보장하는 규약
- e-mail, FTP, 웹(HTTP) 등이 TCP에서 동작하는 응용프로그램
- IP
- IP(Internet Protocol) 패킷 교환 네트워크에서 송신 호스트와 수신 호스트가 데이터를 주고 받는 것을 관장하는 프로토콜
- TCP보다 하위 레벨 프로토콜
- 주소를 보고 찾아 갈 수 있게 해주는 프로토콜
- IP 주소
- 네트워크 상에서 유일하게 식별 될 수 있는 컴퓨터 주소(4개의 숫자가 '.'으로 연결 되어 있음 => 192.156.11.15)
- 숫자로 된 주소는 기억하기 어려우므로 문자열로 구성된 도메인 이름으로 바꿔 사용(www.nave.com)
- DNS(Domain Name Server) => 문자열로 구성된 도메인 이름을 숫자로 구성 된 IP 주소로 자동 변환
- 현재는 32비트의 IP 버전 4(IPv4) 사용 중이지만 주소 고갈로 인해 128비트의 IP 버전 6(IPv6)이 점점 사용되는 추세
- 네트워크 상의 컴퓨터 또는 시스템을 식별하는 주소
- PORT
- 컴퓨터가 하나 이상의 역할을 하기 위해 포트를 열어서 사용(web 80, DB 1500 ....)
- 통신하는 프로그램 간에 가상의 연결단인 포트 생성 => 포트 번호를 이용하여 통신할 응용프로그램 식별
- 모든 응용프로그램은 하나 이상의 포트 생성 가능 => 포트를 이용하여 상대방 응용프로그램과 데이터 교환
- 잘 알려진 포트(well-know ports)로는 0~1023 사이의 포트 번호가 있음 => 텔넷 23, HTTP 80, FTP 21
- 개발자는 잘 알려진 포트 번호는 사용하지 않는 것이 좋음(충돌 가능성 있기 때문)
- URL을 이용한 웹 프로그래밍
- URL(Uniform Resource Locator)은 인터넷 상의 리소스에 대한 주소
- URL 구조
- 프로토콜 식별자(protocol identifier)://자원 이름(resource name)
- http://www.naver.com/
- 자원 이름(resource name)
- 사용되는 프로토콜에 따라서 그 구성이 달라짐
- http:호스트이름/파일이름:포트번호(8080)
- https:호스트이름/파일이름:포트번호(443)
- 사용되는 프로토콜에 따라서 그 구성이 달라짐
자바의 URL 클래스
- java.net 패키지에 포함
- 웹 상의 자원을 지정하는 URL을 나타냄
URL 객체
- URL(String spec) : 문자열이 지정하는 자원에 대한 URL 객체를 생성
- URL(String protocol, String host, int port, String file) : 프로토콜 식별자, 호스트 주소, 포트 번호, 파일 이름이 지정하는 자원에 대한 URL 객체 생성
- URL(String protocol, String host, String file) : 프로토콜 식별자, 호스트 주소, 파일 이름이 지정하는 자원에 대한 URL 객체 생성
- URL(URL context, String spec) : URL 객체 context에 대한 상대 경로가 지정하는 자원에 대한 URL 객체 생성
자바의 URL 클래스의 주요 메소드
- Object getContent() : URL의 컨텐트를 반환
- String getFile() : URL 주소의 파일 이름 반환
- String getHost() : URL 주소의 호스트 이름 반환
- String getPath() : URL 주소의 경로 부분 반환
- int getPort() : URL 주소의 포트 번호 반환
- int getLocalPort() : 소켓이 연결된 로컬 포트 번호 반환
- int getPort() : 소켓이 연결한 서버의 포트 번호 반환
- inputStream openStream() : URL에 대해 연결을 설정하고 이 연결로부터 입력을 받을 수 있는 InputStream 객체 반환
- URLConnection openConnection() : URL 주소의 원격 객체에 접속한 뒤 통신 할 수 있는 URLConnection 객체 리턴
자바의 URL 객체 생성 방법
- 절대 경로로 URL 객체 생성
- URL homePage = new URL("http://news.hankooki.com");
- 상대 경로로 URL 객체 생성 : 잘못된 주소의 URL 입력시 MalformedURLException 예외 발생
- URL opinion = new URL(homePage, "opinion/editorial.htm");
- URL 객체에서 데이터 읽기
- openStream() 메소드로 스트림 생성해서 URL 객체가 가리키는 주소에서 데이터를 가져옴
- openStream()이 리턴하는 InputStream 객체를 이용하여 일반 스트림 입력을 수행
URL 객체 예제
package natwork;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
public class URLRead {
public static void main(String[] args) {
try {
//네트워크 세계
URL url = new URL("https://www.naver.com/");
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
//자바의 세계
String line;
while((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
URLConnection 클래스
- 주어진 원격지의 주소 URL에 네트워크 접속 후 데이터를 보내거나 받을 수 있도록 하는 기능
URLConnection 클래스의 주요 메소드
- abstract void connect() : URL에 의해 참조되는 외부 리소스와 통신 연결 설정
- Object getContent() : URL 연결에서 컨텐트를 가져옴
- String getContentEncoding() : 컨텐트 인코딩 필드를 반환
- int getContentLength() : 컨텐트 길이 필드 반환
- String getContentType() : 컨텐트 타입 필드 반환
- boolean getDoInput() : URLConnection 객체의 doInput 필드 값 반환
- boolean getDoOutput() : URLConnection 객체의 doOutput 필드 값 반환
- InputStream getInputStream() : 설정된 연결에서 데이터를 읽을 입력 스트림 반환
- OuputStream getOutputStream() : 설정된 연결로 데이터를 출력할 출력 스트림 반환
- URL getURL() : URLConnection 객체의 URL 필드 값 반환
- void setDoInput(boolean doInput) : URLConnection 객체의 doInput 필드 값 설정
- void setDoOutput(boolan doOutput) : URLConnection 객체의 doOutput 필드 값 설정
URL 객체 생성 방법
- URL.openConnection() 이용
URL aURL = new URL("https://www.naver.com/");
URLConnection uc = aURL.openConnection(); // 원격지와 연결한다.
- URLConnection 생성자 이용 : 연결하기 전 여러가지 인자들과 요청과 관련된 속성들 설정 가능
URL aURL = new URL("https://www.naver.com/");
URLConnection uc = new URLConnection(aURL);
uc.connect(); //원격지와 연결한다.
URLConnection을 이용하여 원격지로 데이터 보내기
- URLConnection 객체에서 데이터 쓰기
- 웹 서버에 데이터를 요청하여 읽어올 때 주로 HTTP GET 사용
- 웹 서버에 데이터를 요청 할 때 같이 처리 될 데이터를 보낼 때 HTTP POST 사용
- URLConnection 객체는 HTTP POST 방식으로 서버에 데이터 전송
HTTP POST 사례
- 회원가입시 성과 이름을 입력하는 필드가 폼(form)
- 필드에 데이터를 입력한 후 전송 버튼을 누르면 웹 서버로 데이터를 전송해야 하는데 이 데이터를 보내는 방법
웹 서버에 데이터를 보내기 위해서 필요한 단계
- URL 생성
- URL 객체에서 URLConnection 객체를 얻어온다.
- setDoOutput() 메소드로 doOuput 필드를 true로 설정
- connect() 메소드로 연결 설정
- 연결에서 출력 스트림을 얻어 온다.
- 출력 스트림에 데이터를 출력
- 출력 스트림을 닫는다.
package natwork;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class URLConnectionWriter {
public static void main(String[] args) {
try {
//POST가 가능한 사이트 URL 객체 생성
URL aURL = new URL("");
//URL 객체에서 URLConnection 객체 생성
URLConnection uc = aURL.openConnection();
//출력 모드 설정
uc.setDoOutput(true);
//출력 스트림 설정
OutputStreamWriter out = new OutputStreamWriter(uc.getOutputStream());
//서버에 데이터 보내기
out.write("fname=Kitea&lname=Hwang");
out.close();
//입력 스트림 생성
BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String inputLine;
while((inputLine = in.readLine()) != null) //한행 씩 읽음
System.out.println(inputLine);
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
소켓 프로그래밍
소켓(socket)
- 네트워크 상에서 수행되는 두 프로그램 간의 양방향 통신 링크의 한쪽 끝 단을 의미
- 특정 포트 번호와 연결되어 있음(TCP에서 데이터를 보낼 응용프로그램을 식별 할 수 있음)
- 자바에서의 데이터 통신 시 소켓 사용
- 소켓 종류 : 서버 소켓, 클라이언트 소켓

소켓을 이용한 서버 클라인트 통신 프로그램의 구조
클라이언트 소켓 =접속=> 서버 소켓 => 소켓 생성 => 소켓과 클라이언트끼리 소통
- 클라이언트 소켓이 지정된 IP주소와 포트번호에 맞는 서버 소켓에 접속
- 서버 접속 시 소켓이 생성
- 소켓과 클라이언트과 소통
Socket 클래스
- 클라이언트 소켓에 사용되는 클래스
- java.net 패키지에 포함
- 주요 생성자
- Socket(IntAddress address, int port) : 소켓을 생성하여 지정된 IP 주소와 포트 번호에 연결
- Socket(String host, int port) : 소켓을 생성하여 지정된 호스트와 포트 번호에 연결. 호스트 이름이 null인 경우는 루프백(loopback) 주소로 가정
- 주요 메소드
- void close() : 소켓을 닫음
- void connect(SocketAdress endpoint) : 소켓을 서버에 연결
- InetAddress getInetAddress()
- InputStream getInputStream() : 소켓에 대한 입력 스트림 반환
- InetAddress getLocalAddress()
- int getLocalPort()
- int getPort()
- OutputStream getOutputStream() : 소켓에 대한 출력 스트림 반환
소켓 생성, 서버 접속, 입출력 스트림 생성
- 클라이언트 소켓 생성 및 서버에 접속 : Socket 객체가 생성되면 곧 바로 IP주소로 자동 접속
- Socket clientSocket = new Socket("IP", 포트번호);
2. 네트워크 입출력 스트림 생성 : 일반 스트림을 입출력 하는 방식과 동일
- BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));
3. 서버로 데이터 전송 : flush()를 호출하면 스트림 속에 데이터를 남기지 않고 모두 전송
- out.write("hello"+"\n");
out.flush();
4. 서버로부터 데이터 수신
- int x = in.read(); //서버로부터 한 개의 문자 수신
String line = in.readline(); //서버로부터 한 행의 문자열 수신
5. 네트워크 접속 종료
- clientSocket.close();
ServerSocket 클래스, 서버 소켓
- 서버 소켓에 사용되는 클래스
- java.net 패키지에 포함
- 주요 생성자
- ServerSocket(int port) : 소켓을 생성하여 지정된 포트 번호에 연결
- 주요 메소드
- Socket accept() : 연결 요청을 기다리다 연결 요청이 들어오면 수락하고 새 Socket 객체를 반환
- void close()
- InetAddress getInetAddress()
- int getLocalPort()
- boolean isBound()
- boolean isClosed()
- void setSoTimeout(int timeout)
클라이언트와 서버
클라이언트와 서버 연결
- 서버는 서버 소켓으로 들어오는 연결 요청을 기다림 (서버 - 포트 - listen)
- 클라이언트가 서버에 연결 요청(클라이언트 - 포트 ==연결요청==> listen - 포트 - 서버)
- 서버가 연결 요청 수락, 새로운 소켓 생성 후 클라이언트와 연결(새로운 소켓 - 서버포트 <==연결==> 클라이언트포트)
서버소켓 생성, 클라이언트 접속, 입출력 스트림 생성
1. 서버 소켓 생성 : 이미 사용 중인 포트 번호 지정 시 오류 발생 주의
- ServerSocket serverSocket = new ServerSocket(포트번호);
2. 클라이언트로부터 접속 기다림 : accept() 메소드는 연결 요청이 오면 새로운 Socket 객체 반환
- 서버에서 클라이언트와의 데이터 통신은 새로 만들어진 Socket 객체를 통해 이루어짐
- Socket socket = serverSocket.accept();
3. 네트워크 입출력 스트림 생성 : 일반 스트림을 입출력 하는 방식과 동일하게 네트워크 데이터 입출력
- accept() 메소드에서 얻은 Socket 객체의 getInputStream()과 getOutputStream()메소드를 이용하여 데이터 스트림 생성
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
클라이언트로 데이터 송수신
1. 클라이언트로부터 데이터 수신
- int x = in.read(); // 클라이언트로부터 한 개의 문자 수신
- String line = in.readline(); //클라이언트로부터 한 행의 문자열 수신
2. 클라이언트로 데이터 전송
- out.write("Hi"+"\n")
- out.flush() //스트림 속에 데이터 남기지 말고 모두 전송
3. 네트워크 접속 종료
- socket.close();
4. 서버 응용프로그램 종료 : 더 이상 클라이언트의 접속을 받지 않고 서버 응용 프로그램을 종료하고자 하는 경우
- serverSocket.close();
소켓을 이용한 클라이언트/서버 채팅
간단한 채팅 프로그램 예제(1:1 채팅 하는 간단한 예제)
기능정리
- 서버와 클라이언트 간의 메시지 구분을 위해 서버는 메시지 앞에 "서버>"를 접두어로 붙여 메시지를 전송한다.
- 서버와 클라이언트가 번갈아 가면서 메시지 전송 및 수신
- 클라이언트가 bye를 보내면 프로그램 종료
서버 프로그램
1. 서버 소켓 생성
- 시스템에서 사용되지 않는 포트 번호로 서버 소켓 생성
- ServerSocket listener = new ServerSocket(포트번호);
2. 클라이언트 요청 대기
- 클라이언트가 연결 요청이 올 때까지 소켓 기다림
- 해당 포트 번호로 연결 요청이 오면 연결을 수락하고 새로운 소켓을 생성 후 새 소켓으로 클라이언트와 통신
- 새로운 소켓의 포트 번호는 자동으로 할당
3. 클라이언트와 통신을 위한 입출력 스트림 생성
- 스트림을 생성하여 클라이언트와 데이터 송수신
- 데이터의 종류에 따라 바이트 스트림 또는 문자 스트림을 생성
- 채팅과 같이 문자열을 송수신하는 경우는 문자 스트림 사용
- 효율적인 입출력을 위하여 버퍼 스트림(Buffered Stream) 사용
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
4. 클라이언트의 데이터 수신
- 스트림 생성 이후는 데이터 입력 받는 방법과 동일
- 클라이언트에서 한 행의 문자열을 보내올 때까지 기다림
- String inputMessage = in.readLine();
5. 클라이언트의 데이터 송신
- 스트림 생성 이후는 일반 데이터를 출력하는 방법과 동일
- 콘솔에서 입력 받은 문자열을 클라이언트로 송신
- flush() 메소드로 스트림의 모든 데이터를 클라이언트로 송신
- String outputMessage = stin.readLine();
out.write("서버>" + outputMessage + "\n");
out.flush();
6.연결 종료
- 데이터 송수신이 끝나면 소켓 닫음
- 소켓을 닫으면 소켓의 입출력 스트림도 같이 닫힘
- 서버 소켓을 닫으면 클라이언트 연결 요청 받을 수 없음
- socket.close();
listener.close();
클라이언트 프로그램
1. 연결 요청 : 소켓생성(서버의 호스트 주소, 서버가 연결 요청을 모니터링하는 포트 번호로 소켓 생성)
- socket = new Socket("localhost", 포트번호); // 동일한 시스템에서 동작하기 때문에 IP주소는 localhost로 지정
2. 클라이언트와 통신을 위한 입출력 스트림 생성
- 스트림을 생성하여 서버와 데이터 송수신
- 데이터 종류에 따라 바이트 스트림 또는 문자 스트림 사용
- 채팅과 같이 문자열을 송수신하는 경우는 문자 스트림 사용
- 효율적 입출력을 위하여 버퍼 스트림(Buffered Stream) 사용
- BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
3. 서버에 데이터 송신
- 스트림 생성 이후는 데이터 출력 방법과 동일
- 콘솔에서 입력 받은 문자열을 서버로 송신
- flush() 메소드로 스트림의 모든 데이터를 서버로 송신
- String outputMessage = stin.readLine();
out.write("클라이언트>"+outputMessage+"\n");
out.flush();
4. 클라이언트의 데이터 수신
- 스트림 생성 이후는 데이터 입력 방법과 동일
- 서버에서 한 행의 문자열을 보내 올 때까지 기다림
- String inputMessage = in.readLine();
5. 연결 종료
- 데이터의 송수신이 끝나면 소켓 닫아야 함
- 소켓을 닫으면 소켓의 입출력 스트림도 같이 닫힘
- socket.close();
간단한 1:1채팅 프로그램 예제 코드
서버
package chat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class ServerEx {
public static void main(String[] args) {
ServerSocket server = null;
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
Scanner sc = new Scanner(System.in);
try {
server = new ServerSocket(9999);
System.out.println("서버시작 : 연결 대기중....");
socket = server.accept();
System.out.println("클라이언트와 연결 됨");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while(true) {
String inMsg = in.readLine();
if(inMsg.equalsIgnoreCase("bye")) {
System.out.println("클라이언트가 나감");
break;
}
//정상 메시지인 경우
System.out.println("클라이언트 : "+ inMsg);
System.out.println("보내기 >>");
String outMsg = sc.nextLine();
out.write(outMsg + "\n");
out.flush();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
sc.close();
out.close();
in.close();
socket.close();
server.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
클라이언트
package chat;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
public class ClientEx {
public static void main(String[] args) {
Socket socket = null;
BufferedReader in = null;
BufferedWriter out = null;
Scanner sc = new Scanner(System.in);
try {
socket = new Socket("localhost", 9999);
System.out.println("서버에 연결 됨");
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
while(true) {
System.out.println("보내기>>");
String outMsg = sc.nextLine();
if(outMsg.equalsIgnoreCase("bye")) {
out.write(outMsg + "\n");
out.flush();
System.out.println("접속 종료!!!");
break;
}
//정상 메시지인 경우
out.write(outMsg + "\n");
out.flush();
String inMsg = in.readLine();
System.out.println("서버>>" + inMsg);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
sc.close();
out.close();
in.close();
socket.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
'프로젝트 > mini project' 카테고리의 다른 글
[JSP MVC1 : GoGoTaiwan] JSP를 이용한 MVC1 패턴의 웹사이트 (0) | 2021.12.04 |
---|---|
[Frontend : MainPageExample] 웹사이트 Main 페이지 (0) | 2021.10.30 |
[Frontend : DropDownExample] 드롭다운형식 메뉴바 (0) | 2021.10.18 |
[Frontend : CodingStudy] Frontend 웹페이지 + 깃헙 웹 호스팅 (0) | 2021.01.04 |