ネットワーク
8874 ワード
index.htmlファイルを作成して、コードを実行して、住所を書いて実行することができます!
package ex07.network.simpleWebServer06;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* https://www.naver.com
* https://www.naver.com/index.html
*
https:// => http프로토콜에 secure를 적용했다
www.naver.com => 주소 (DNS Server에서 요청하면 ip를 알려준다)
index.html => 나 이 페이지 다운로드해줘
브라우저 내부의 렌더링 엔진 : 화면을 구성
*/
public class SimpleWebServer {
public final static int PORT = 80; // http 포트
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(PORT);
while (true) {
System.out.println("[서버] 브라우저 접속 대기...");
Socket sock = server.accept();
System.out.println("[서버] 새로운 스레드 생성...");
HttpThread ht = new HttpThread(sock);
ht.start();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
class HttpThread extends Thread {
Socket sock;
BufferedReader br;
PrintWriter pw;
public HttpThread(Socket sock) {
this.sock = sock;
try {
// 읽기 객체
br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
// 쓰기 객체
pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public void run() {
BufferedReader fbr = null;
try {
// 1. 브라우저가 보내는 데이터를 얻는다
// 원하는 파일이름을 추출한다
String line = br.readLine();
System.out.println("-----<브라우저 데이터>-----");
System.out.println(line);
System.out.println("-------------------------");
// 파일이름이 있으면 추출하자
int start = line.indexOf(" ") + 2;
int end = line.lastIndexOf("HTTP") - 1;
String filename = line.substring(start, end);
// 명시적인 파일이름이 있으면 그 파일을 전달하고,
// 파일 이름을 명시하지 않으면 그냥 index.html로 정해주겠다
if(filename.equals(""))
filename = "index.html";
System.out.println("브라우저가 " + filename + "을 요청");
// 2. 파일에서 데이터를 읽는다
// 파일을 읽기 위해 객체와 연결시키자
fbr = new BufferedReader(new FileReader(filename));
// 3. 브라우저에 전송한다
// 파일을 읽어서 브라우저(클라이언트)에 전송하자
System.out.println("-----<서버 전송>-----");
while(true) {
// 요청 파일을 읽어서 1줄씩 전달하자
String fline = fbr.readLine();
if(fline==null) // 더 이상 읽을 것이 없으면 탈출
break;
System.out.println(fline);
pw.println(fline);
pw.flush();
}
System.out.println("------------------------");
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}finally {
try {
if(fbr!=null) fbr.close();
if(br!=null) br.close();
if(pw!=null) pw.close();
if(sock!=null) sock.close();
}catch(Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
}
サーバー
package ex07.network.cmdPacketServer07;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
//서버는 서비스를 제공하는 프로그램을 일컫는다.
//1) 고정된 주소를 가진다(주소를 부여)
//2) 접속 요청하는 클라이언트를 받아줘야 한다(accept)
//3) 요청을 받아들이면 내부에서는 2개 스트림이 형성된다
//4) 스트림이 형성되면 송수신이 가능하다
//5) 작업이 완료되면 close를 통해 스트림을 해제한다
//
//EchoServer : 클라이언트가 보내온 데이터를 그래도 돌려주는
// 서버
public class CmdPacketServer {
public static String[] parsePacket(String line) {
String[] params = line.split("\\|"); //이 글자를 기준으로 자르겠다
return params;
}
public static String runCmd(String cmd, int num0, int num1) {
int result = 0;
switch(cmd) { //cmd의 종류에 따라 값0과 값1의 처리를 다르게.
case "+": result = num0 + num1; break;
case "-": result = num0 - num1; break;
case "*": result = num0 * num1; break;
case "/": result = num0 / num1; break;
}
return result + "";
}
public static void main(String[] args) {
try {
// 1) 소켓 객체 생성한다
// : tcp/udp와 연결하기 위한 소켓 객체 생성
// : 소켓에는 클라이언트가 찾아오기 위한 주소 부여
// 소켓 객체 생성,
// 주소 : ip, port
// ip: Host(PC)를 찾기 위한 주소
// port: 프로세스들이 상대방과 통신하려고 약속된
// 번호
// 192.168.0.13 9000이렇게 지정한 Client만
// 이 서버와 통신 가능
// ip는 따로 설정하지 않아도 Host의 주소를 사용
// port : 9000
ServerSocket server = new ServerSocket(9000);
// 클라이언트가 접속하기를 대기(여기서 멈춰있음)
// 클라이언트와 연결되면 연결 소켓을 반환
// 이 연결소켓으로 통신을 할 수 있다
// ex)VIPS를 방문하면 입구에 안내직원(server)
// 이 대기하라고 하고 서비스 직원(sock)을 연결시켜준
System.out.println("클라이언트 접속 대기...");
Socket sock = server.accept();
// 연결이 되면 상대방의 주소를 알 수 있다
InetAddress inetAddr = sock.getInetAddress();
System.out.println(inetAddr.getHostAddress() + "로부터 접속");
// 연결이 되었으니까 통신을 하자
// 통신하는 스트림객체를 얻어오자
OutputStream out = sock.getOutputStream();
OutputStreamWriter outW = new OutputStreamWriter(out);
PrintWriter pw = new PrintWriter(outW);
InputStream in = sock.getInputStream();
InputStreamReader inR = new InputStreamReader(in);
BufferedReader br = new BufferedReader(inR);
while (true) {
// 클라이언트가 보내는 데이터를 기다리자
String line = br.readLine();
if (line == null) {
System.out.println("클라이언트와 연결 X");
break;
}
System.out.println("클라이언트로부터 수신 : " + line);
String[] params = parsePacket(line);
String result = runCmd(params[0],
Integer.parseInt(params[1]),
Integer.parseInt(params[2]));
System.out.printf("%s %s %s = %s",
params[1], params[0],
params[2], result);
pw.println(result); // 클라이언트에 결과값 전송
pw.flush(); // 버퍼에 남기지 말고 즉시
}
System.out.println("클라이언트-서버 연결 종료");
pw.close();
br.close();
sock.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
クライアント
package ex07.network.cmdPacketClient08;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
/*
클라이언트 프로그램
1) 서버의 주소(ip, port)를 가지고 서버에 접속(connect)
2) 접속 후에 통신이 가능
3) 접속중단은 close
[서버와 클라이언트 간에는 약속이 필요하다 ]
==> 약속 == 프로토콜
cmd|값0|값1
cmd의 종류에 따라 값0과 값1의 처리를 다르게 한다
cmd : 처리를 결정
ex)
A|코로나 조심하세요 => Alarm 메시지
I|진황의 검|물약|물약|포션|단검 => Information
P|I|253.34|345.23|345.56 => 위도 경도 고도 position Interval 전송
P|E|253.34|345.23|345.56 => 위도 경도 고도 position Emergency 전송 (정해주기나름)
*/
public class CmdPacketClient {
public static void main(String[] args) {
try {
// 127.0.0.1 : 현재 나의 Host의 주소, loop 주소
// Socket sock = new Socket("192.168.0.13", 9000);
// Socket생성자에서 내부적으로 connect를 진행
// 객체가 만들어지면 서버와 이미 연결 상태
Socket sock = new Socket("127.0.0.1", 9000);
// 키보드 데이터 입력 객체 생성
InputStreamReader inK =
new InputStreamReader(System.in);
BufferedReader keyboard =
new BufferedReader(inK);
// 통신 스트림 객체
OutputStream out = sock.getOutputStream();
OutputStreamWriter outW =
new OutputStreamWriter(out);
PrintWriter pw = new PrintWriter(outW);
InputStream in = sock.getInputStream();
InputStreamReader inR =
new InputStreamReader(in);
BufferedReader br = new BufferedReader(inR);
while(true) {
System.out.print("연산자 입력(+ - * / quit) >> ");
String cmd = keyboard.readLine();
if(cmd.equals("quit")) {
System.out.println("클라이언트 종료");
break;
}
System.out.print("첫번째 숫자 입력 >> ");
int num0 = Integer.parseInt(keyboard.readLine());
System.out.print("두번째 숫자 입력 >> ");
int num1 = Integer.parseInt(keyboard.readLine());
//약속대로 패킷 구성
String line = String.format("%s|%d|%d", //이런식으로 보낸다. 연산자(문자열,숫자,숫자)
cmd, num0, num1);
System.out.println("서버로 패킷 전송 : " + line);
pw.println(line);
pw.flush();
// 서버가 echo하는 것을 받아서 출력
String echo = br.readLine();
System.out.println("서버로부터 수신 : " + echo);
}
pw.close();
outW.close();
out.close();
br.close();
inR.close();
in.close();
sock.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
Reference
この問題について(ネットワーク), 我々は、より多くの情報をここで見つけました https://velog.io/@jinkyung/네트워크テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol