TCP/IP 프로토콜
두 시스템 간에 데이터가 손상없이 안전하게 전송되도록 하는 통신 프로토콜(신뢰적 전송)
→ TCP에서 동작하는 응용프로그램 사례 e-mail, FTP, 웹(HTTP) 등
→ 연결형 통신 한 번 연결 후 계속 데이터 전송 가능
소켓이 만들어지는 과정(3-way handshake)
1) 소켓생성
Client Server(198.10.2.1) : 9000
2)서버의 ip, port 번호로 접속을 시도 3)ServerSocket(accept)→4)Socket 5)소켓으로부터 클라이언트 접속
6)서버로 접속하기 위해 내부포트 열림
예시)
Chat Server
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
HashMap clients; // client 정보 담아두는 HashMap / 키와 값을 저장 키는 변경이 안됨.
ChatServer() {
clients = new HashMap();
Collections.synchronizedMap(clients); //해시맵 동기화 하여 여러 스레드에서 접근가능
}
public void start() { //서버시작
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(9999); // 1. 포트 9999를 사용하여 서버소켓을 생성
while (true) {
socket = serverSocket.accept(); // 2. , 클라이언트 연결 대기
System.out.println("서버 시작");
System.out.println(socket.getInetAddress() + " " + socket.getPort());
Receiver Thread = new Receiver(socket); // 클라이언트 연결을 처리할 Receiver스레드 생성
Thread.start(); // class Receiver extends Thread
}
} catch (Exception e) {
}
}
void sendAll(String msg) {
Iterator iterator = clients.keySet().iterator(); // 모든 클라이언트의 이름을 가져오는 반복자 생성
while (iterator.hasNext()) {
try {
DataOutputStream out = (DataOutputStream) clients.get(iterator.next());
out.writeUTF(msg); 모든 클라이언트에게 메세지 전송
} catch (Exception e) {
}
}
}
public static void main(String[] args) {
new ChatServer().start();
}
class Receiver extends Thread { //내부클래스
Socket socket;
DataInputStream in;
DataOutputStream out;
public Receiver(Socket socket) {
this.socket = socket;
try {
in = new DataInputStream(socket.getInputStream()); // 입력 스트림 생성
out = new DataOutputStream(socket.getOutputStream()); // 출력 스트림 생성
} catch (Exception e) {
}
}
public void run() {
String name = "";
try {
name = in.readUTF(); // 클라이언트 쪽에서 보낸 메시지,이름을 읽는다
if (clients.get(name) != null) { // 이미 사용중인 이름인지 확인
out.writeUTF("이미 사용중인 닉네임입니다" + name); // 사용중인 경우 클라이언트에게 알림
out.writeUTF("다른 아이디를 입력하세요");
System.out.println(socket.getInetAddress()+":"+socket.getPort()+"Disconnect");
in.close();
out.close();
socket.close();
socket = null;
} else {
sendAll("#"+name + "이 입장하였습니다."); // 모든 클라이언트에게 새로운 클라이언트 입장을 알림
clients.put(name, out); // 클라이언트 정보를 해시맵에 추가
while (in != null) {
sendAll(in.readUTF()); //클라이언트로부터 메세지를 읽어 모든 클라이언트에게 전송
}
}
} catch (Exception e) {
} finally {
if(socket!=null) {
sendAll("#"+name+"종료!"); 모든 클라이언트에게 클라이언트 종료를 알림
clients.remove(name); // 클라이언트 정보를 해시멥에서 제거
System.out.println(socket.getInetAddress()+":"+socket.getPort()+"Disconnect");
}
}
}
}
}