서버 소켓 준비
=> 가게문을 연다 -> 손님을 기다린다 (Listener)
accept();
=> 손님과 연결된 소켓(socket)을 얻는다
대부분의 서버는 클라이언트가 먼저 정보를 보냄 (요구사항)
서버입장에서는 클라이언트가 보낸 원하는 정보를 읽음 => InputStream
Data를 보냄 => OutputStream
public class Server1 {
//bad code
public static void main(String[] args) throws Exception {
//단순히 이거만 있으면 안되고 accept가 필요함
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("Ready...");
//누군가 접속될 때까지 멈췄다 실행되는 구조 - Blocked
for(int i = 0; i < 10; i++) {
Socket client = serverSocket.accept();
System.out.println(client);
//외부에서 연결 들어오면 해당 포트 정보가 찍히는 구조
}//end for
}//end main
}//end class
클라이언트가 없는데?? => 아님 브라우저가 클라이언트가 되는 것
맨 위에 addr=/0:0:0:0:0:0:0:1, ... 이부분이 브라우저가 접속했다는 뜻
다른 사람이 접속 시 addr 부분에 해당 접속자의 IP주소 뜸
Server1.java 수정
public class Server1 {
//bad code
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("Ready...");
for(int i = 0; i < 10; i++) {
Socket client = serverSocket.accept();
System.out.println(client);
//읽어오기 => InputStream
//Scanner에 in으로 읽어온거 스캔
//nextLine() -> 한 라인만 읽어옴
InputStream in = client.getInputStream();
Scanner inScanner = new Scanner(in);
String line = inScanner.nextLine();
System.out.println(line);
//클라이언트와 연결된 빨대가 생긴 셈
OutputStream out = client.getOutputStream();
//보낼 메세지 - html 코드로 작성
String msg = "<h1>Hello World</h1>";
//out.write(msg.getBytes(StandardCharsets.UTF_8));
//위의 코드만 작성 시 결과가 제대로 출력되지 않는다
//Data는 제대로 전송됐는데 왜??
//아래의 4줄 코드로 변경 시 제대로 Hello World가 출력되는 것을 볼 수 있음
//HTTP에 맞는 전송방식이 아니어서(?) - 브라우저가 읽을 수 없는 코드였기때문에
out.write(new String("HTTP/1.1 200 OK\r\n").getBytes());
out.write(new String("Cache-Control: private\r\n").getBytes());
out.write(new String("Content-Length: "+msg.getBytes("UTF-8").length+"\r\n").getBytes());
out.write(new String("Content-Type: text/html; charset=UTF-8\r\n\r\n").getBytes());
out.write(msg.getBytes(StandardCharsets.UTF_8));
}//end for
}//end main
}//end class
Server1.java를 실행하게되면 브라우저에선 아래처럼 출력되고
서버쪽에는 이렇게 출력되는데 전송된 것 중에 제일 첫번째 줄만 읽어오게 작성했기때문에 request 의 제일 첫 줄만 출력하는 것
public class Server2 {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("Ready...");
for (int i = 0; i < 10; i++) {
Socket client = serverSocket.accept();
System.out.println(client);
File file = new File("C:\\zzz\\aaa.jpg");
OutputStream out = client.getOutputStream();
out.write(new String("HTTP/1.1 200 OK\r\n").getBytes());
out.write(new String("Cache-Control: private\r\n").getBytes());
out.write(new String("Content-Length: " + file.length() + "\r\n").getBytes());
out.write(new String("Content-Type: image/jpeg\r\n\r\n").getBytes());
//out.write(new String("Content-Type: text/html; charset=UTF-8\r\n\r\n").getBytes()); -> text/html => error
Files.copy(file.toPath(), out);
}//end for
}//end main
}//end class
이미지를 출력할 때 Content-Type을 이미지에 맞게 변환하지않고 그냥 text/html
로 전송시 브라우저는 이미지를 이미지가 아닌 텍스트로 판단해서 깨진 글자가 출력됨
Content-Type을 이미지에 맞게 image/jpeg로 변경해주어서 에러가 발생하지 않고 정상출력됨
= 미디어 타입(media type), MIME 타입(MIME type)
1) Multipart Related MIME 타입
- Content-Type: Multipart/related <-- 기본형태
- Content-Type: Application/X-FixedRecord
2) XML Media의 타입
- Content-Type: text/xml
- Content-Type: Application/xml
- Content-Type: Application/xml-external-parsed-entity
- Content-Type: Application/xml-dtd
- Content-Type: Application/mathtml+xml
- Content-Type: Application/xslt+xml
3) Application의 타입
- Content-Type: Application/EDI-X12 <-- Defined in RFC 1767
- Content-Type: Application/EDIFACT <-- Defined in RFC 1767
- Content-Type: Application/javascript <-- Defined in RFC 4329
- Content-Type: Application/octet-stream : <-- 디폴트 미디어 타입은 운영체제 종종 실행파일, 다운로드를 의미
- Content-Type: Application/ogg <-- Defined in RFC 3534
- Content-Type: Application/x-shockwave-flash <-- Adobe Flash files
- Content-Type: Application/json <-- JavaScript Object Notation JSON; Defined in RFC 4627
- Content-Type: Application/x-www-form-urlencode <-- HTML Form 형태
* x-www-form-urlencode와 multipart/form-data은 둘다 폼 형태이지만 x-www-form-urlencode은 대용량 바이너리 테이터를 전송하기에 비능률적이기 때문에 대부분 첨부파일은 multipart/form-data를 사용하게 된다.
4) 오디오 타입
- Content-Type: audio/mpeg <-- MP3 or other MPEG audio
- Content-Type: audio/x-ms-wma <-- Windows Media Audio;
- Content-Type: audio/vnd.rn-realaudio <-- RealAudio; 등등
5) Multipart 타입
- Content-Type: multipart/mixed: MIME E-mail;
- Content-Type: multipart/alternative: MIME E-mail;
- Content-Type: multipart/related: MIME E-mail <-- Defined in RFC 2387 and used by MHTML(HTML mail)
- Content-Type: multipart/formed-data <-- 파일 첨부
6) TEXT 타입
- Content-Type: text/css
- Content-Type: text/html
- Content-Type: text/javascript
- Content-Type: text/plain
- Content-Type: text/xml
7) file 타입
- Content-Type: application/msword <-- doc
- Content-Type: application/pdf <-- pdf
- Content-Type: application/vnd.ms-excel <-- xls
- Content-Type: application/x-javascript <-- js
- Content-Type: application/zip <-- zip
- Content-Type: image/jpeg <-- jpeg, jpg, jpe
- Content-Type: text/css <-- css
- Content-Type: text/html <-- html, htm
- Content-Type: text/plain <-- txt
- Content-Type: text/xml <-- xml
- Content-Type: text/xsl <-- xsl