데이터 계층이 내려갈때마다 pdu들이 다른 계층의 payload로 들어가면서 길어진다.(캡슐화)
다른 클라이언트가 받은 패킷은 header를 읽고 payload를 역순으로 데이터를 올려보냄
TCP, UDP
TCP (Transmission Control Protocol)
전화에 비유
패킷의 크기가 고정되어 있다.
1packet = 8bit(1byte)
신뢰성 통신 (오류 검출)
속도가 느리다.
오류검출하는 패킷이 존재
미전송 패킷을 다시 보낸다.
중요한 데이터를 보낼 때 사용(결제, 은행거래,..)
Socket, ServerSocket
UDP(User Datagram Protocol)
우편에 비유
패킷의 크기를 변경할 수 있다.(최대 512byte)
비신뢰성 통신 (오류 검출 안함)
속도가 빠르다.
오류검출하는 패킷이 없음
반드시 데이터 전송되리란 보장이 없음
중요하지 않은 데이터를 전달할 때 사용(스트리밍, 화상전화, M2M(machine to machine)
DatagramSocket, DatagramPacket
컴퓨터 환경의 변천사
중앙 집중식
한개의 서버가 존재, 여러 단말기가 붙은 형태
예) 하이텔 단말기
서버가 제공하는 데이터를 접목하여 사용
RAIDUS 과금형태
Client - Server
서버가 존재하고 여러 클라이언트가 서버에 데이터를 요청하는 형태
프로그램 배포에 문제
문제 생기면 출장..
Web 환경
웹서버가 존재, 웹 클라이언트(웹브라우저)들이 데이터를 요청하는 형태
웹서버로부터 화면을 받아 브라우저에서 그린다.
브라우저마다 다르게 그려짐 -> 웹표준 탄생의 계기
어디서나 접근가능(접근성)
RIA 환경
RIA(Rich Internet Application)
접속자의 자원을 더 많이 사용
AJAX(Asynchronous JavaScript and XML)
요즘 게임환경은 C/S환경과 Web환경이 합쳐진 형태
Web환경으로 프로그램 배포한 후 웹 브라우저가 감당하기 힘들기 때문에 배포된 프로그램으로 C/S환경으로 게임서버와 게임 클라이언트간 통신
CS와 형태는 같음
Network S/C 프로그래밍
Server
정보제공
ServerSocket 생성
통신 port 열림 : port 선점
1024번 이하의 port는 이미 열려있는 port가 많다.
// 주어진 포트번호로 서버소켓 생성, 접속자가 들어오길 기다림ServerSocket ss = new ServerSocket(포트번호);
접속자 소켓을 받는다.
Socket client = ss.accept(); // blocking
Client
정보를 요청
서버로부터 정보를 제공받는 애
Socket 생성
입력된 ip address와 port를 가지고 서버연결 시도
Socket socket = new Socket(아이피주소,포트번호);
// SimpleServerpublic class SimpleServer { public SimpleServer() throws IOException { // 1. PORT를 열고 접속자가 들어오기를 기다린다. ServerSocket server = null; try { server = new ServerSocket(3000); System.out.println("서버 가동중 "+server); // 3. 접속자가 들어오면 접속자 소켓을 받는다. Socket client = server.accept(); System.out.println("접속자 있음 "+client); } finally { if (server!=null) server.close(); } } public static void main(String[] args) { try { new SimpleServer(); } catch (IOException e) { System.out.println("포트가 이미 사용중입니다."); e.printStackTrace(); } }}
// SimpleClientpublic class SimpleClient { public SimpleClient() throws UnknownHostException, IOException { // 2. 소켓을 생성 : 내 컴퓨터에 들어갈 때는 localhost 또는 127.0.0.1(루프백) // 다른 컴퓨터에 들어갈 때에는 ip address Socket client = new Socket("localhost",3000); System.out.println("서버에 접속 하였습니다. "+client); } public static void main(String[] args) { try { new SimpleClient(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}
방화벽 설정이 안돼 있으면 외부와 통신이 안될 수 있음
제어판에서 인바운드, 아웃바운드 규칙을 추가해 주어 해결
데이터 전송하기
TCP는 패킷이 고정길이 1packet = 8bit(1byte)
Server
접속자 소켓을 받은 후 문자열 쓰기
DataOutputStream 사용
Java의 데이터형을 스트림으로 내보낼 때 사용하는 Stream
DataOutputStream dos = new DataOutputStream(client.getOutputStream());
쓰기
입력된 문자열이 %로 분할(인코딩)되어 스트림에 기록
flush로 스트림에서 분출
dos.writeUTF("문자열");dos.flush();
Client
보내온 문자열을 읽기 위한 스트림을 사용
DataInputStream dis = new DataInputStream(socket.getInputStream())
읽기
인코딩된 한글을 원래대로 조립하여 보여준다.
dis.readUTF();
// 위와 동일한 SimpleServer 예제public SimpleServer() throws IOException { // 1. PORT를 열고 접속자가 들어오기를 기다린다. ServerSocket server = null; // 접속자에게 보내줄 메시지 String msg = "☆ ˚ * ˚★\n" + " ▲ △ ▲ \n" + "(^^)('')('')\n" + "▶◀▶◀▶◀\n" + "메리크리스마스\n" + "해피뉴이어~ -오영근-"; // 접속자에게 메시지를 보내기 위한 스트림을 선언 DataOutputStream dos = null; try { server = new ServerSocket(3000); System.out.println("서버 가동중 "+server); while(true) { // 계속 실행 // 3. 접속자가 들어오면 접속자 소켓을 받는다. Socket client = server.accept(); System.out.println("접속자 있음 "+client); // 접속자에게 메시지를 보내기 위한 연결 dos = new DataOutputStream(client.getOutputStream()); // 얻어낸 스트림에 데이터 쓰기 dos.writeUTF(msg); // 스트림의 데이터를 목적지(소켓)로 분출 dos.flush(); } } finally { if (server != null) server.close(); if (dos != null) dos.close(); }}
public SimpleClient() throws UnknownHostException, IOException { // 2. 소켓을 생성 : 내 컴퓨터에 들어갈 때는 localhost 또는 127.0.0.1(루프백) // 다른 컴퓨터에 들어갈 때에는 ip address Socket client = null; // 서버에서 보내오는 메시지를 읽기위한 스트림 DataInputStream dis = null; try { String ip = JOptionPane.showInputDialog("" + "서버 ip\n130,132.133.134,135,157,146" + ",131,141,142,143,144,155,146,148,149,151,152,153"); client = new Socket("000.00.00."+ip,3000); System.out.println("서버에 접속 하였습니다. "+client); // 소켓에서 스트림 얻기 dis = new DataInputStream(client.getInputStream()); // 서버에서 보내온 메시지 읽기 String revMsg = dis.readUTF(); JOptionPane.showMessageDialog(null, "서버의 메시지 : "+revMsg); } finally { if(client != null) client.close(); if(dis != null) dis.close(); }}