🔎통신의 단계
1) 클라이언트가 호스트 이름/IP주소 및 포트 번호로 지정된 서버에 대한 연결 시작
2) OutputStream을 사용하여 서버에 데이터 전송
3) InputStream을 사용하여 서버에서 데이터를 읽음
4) 연결종료
서버 | 방향 | 클라이언트 |
---|---|---|
클라이언트의 요청을 받기 위한 준비를 한다 (ServerSocket) | ||
클라이언트의 요청을 받아 들인다 (accept) | ← | 서버에 접속 요청을 한다 (Socket) |
클라이언트가 보낸 데이터를 출력한다 (BufferedReader) | ← | 서버에 메시지를 보낸다 (BufferedWriter) |
클라이언트에 메시지를 보낸다 (BufferedWriter) | → | 서버가 보낸 메시지를 출력한다 (BufferedReader) |
종료한다 (Socket.close()) | 종료한다 (Socket.close()) |
클라이언트와 통신할 때 사용하는 클래스
Socket 사용 시 호스트이름과 포트번호를 관리하는 클래스
→ Server Main
package ex03_socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerMain {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// ServerSocket 생성
serverSocket = new ServerSocket();
// InetSocketAddress 생성
InetSocketAddress address = new InetSocketAddress("localhost", 9090); // http://localhost.9090
// ServerSocket에 InetSocketAddress 연결
serverSocket.bind(address);
// serverSocket는 무한루프로 구현
while(true) {
System.out.println("[서버] 클라이언트 접속을 기다리는 중");
// 클라이언트로부터 접속 대기
Socket client = serverSocket.accept();
InetSocketAddress clientAddress = (InetSocketAddress)client.getRemoteSocketAddress();
System.out.println("접속이 허용된 클라이언트 : " + clientAddress.getHostName());
}
} catch(IOException e) {
e.printStackTrace();
}finally {
try {
if(serverSocket.isClosed() == false) {
serverSocket.close();
System.out.println("서버 중지");
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
→ Client Main
package ex03_socket;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
public class ClientMain {
public static void main(String[] args) {
Socket clientSocket = null;
try {
// Soket생성
clientSocket = new Socket();
// 접속할 서버
InetSocketAddress address = new InetSocketAddress("localhost", 9090);
// 서버에 접속
clientSocket.connect(address);
System.out.println("[클라이언트] 접속 성공");
}catch(IOException e) {
e.printStackTrace();
} finally {
try {
if(clientSocket.isClosed() == false) {
clientSocket.close();
}
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
→ Server Main
package ex04_socket;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerMain {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
// ServerSocket 생성
serverSocket = new ServerSocket();
// ServerSocket의 호스트/포트번호 설정
serverSocket.bind(new InetSocketAddress("localhost", 9099));
// 접속한 클라이언트 개수
int clientCnt = 0;
// 서버는 종료 없이 무한루프
while(true) {
System.out.println("[서버] 클라이언트 접속 기다리는 중");
// 클라이언트 접속 및 카운팅
Socket clientSocket = serverSocket.accept();
clientCnt++;
// 클라이언트에게 "Welcome"메시지 전송
// 바이트 출력 스트림 중에서 DataOutputStream은 writeUTF() 메소드를 이용해서
// 한글을 깨짐 없이 보낼 수 있다.
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
out.writeUTF("[서버] 게스트 " + clientCnt + "님 환영합니다!");
// 클라이언트가 보낸 메시지 확인
// 클라이언트가 OutputStreamWriter의 write()로 보냈으므로
// InputStreamReader의 read()로 확인
InputStreamReader in = new InputStreamReader(clientSocket.getInputStream());
char[] cbuf = new char[5];
int readCnt = 0;
StringBuilder sb = new StringBuilder();
while((readCnt = in.read(cbuf)) != -1) {
sb.append(new String(cbuf, 0 ,readCnt));
}
System.out.println("[서버] 클라이언트가 보낸 메시지 : " + sb.toString());
// 입출력 스트림 종료
out.close();
in.close();
// 클라이언트 접속 종료
clientSocket.close();
// 접속한 클라이언트가 3명이면 무한루프 종료
if(clientCnt == 3) {
System.out.println("[서버] 서버가 종료되었습니다.");
serverSocket.close();
break;
}
} // while(true)
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(serverSocket.isClosed() == false) {
System.out.println("[서버] 서버가 종료되었습니다.");
serverSocket.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
}
→ Client Main
package ex04_socket;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.Scanner;
public class ClientMain {
public static void main(String[] args) {
Socket clientSocket = null;
try {
// Socket 생성 및 접속
clientSocket = new Socket();
// 서버 접속
clientSocket.connect(new InetSocketAddress("localhost", 9099));
// 서버에 접속되면 Welcome 메시지가 넘어온다, 받아준다
// 서버가 DataOutputStreamdml writeUTF() 로 메시지를 전송하므로
// 클라이언트는 DataInputStream의 readUTF()로 메시지를 받음
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
String message = in.readUTF();
System.out.println("[클라이언트]" + message);
// Scanner 클래스를 이용해 입력 받은 데이터를 서버로 보내기
Scanner sc = new Scanner(System.in);
System.out.println("서버로 전송할 메시지 >>> ");
String send = sc.nextLine();
OutputStreamWriter out = new OutputStreamWriter(clientSocket.getOutputStream()) ;
out.write(send);
// 입출력 스트림 종료
out.close();
in.close();
sc.close();
} catch(IOException e) {
e.printStackTrace();
}finally {
try {
if(clientSocket.isClosed() == false) {
System.out.println("[클라이언트] 클라이언트 종료");
clientSocket.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
}