ⓐ TCP 방식 (연결성 통신 방법..)
실시간 통신 방식. 신뢰성이 높다.
네트워크 부담이 다소 크다.
ServerSocket, Socket
ⓑ UDP 방식 (비연결성 통신 방법..)
신뢰성의 측면에서 다소 떨어짐.
네트워크 부담이 적은편.
DatagramSocket, DatagramPacket
IP, Domain
Port : 각각의 응용 프로그램이 차지하고 있는 창구(?)
URL(Uniform Resource Locator) : 프로토콜, 도메인, 포트 등 접근하려는 URL에 대한 정보를 얻을 때 사용한다.
InetAddress : IP에 관련된 정보를 얻어올 때 사용한다.
네트워크가 연결된 후에는 소켓이 전송을 담당하게 된다.
서버의 소켓 메소드
ServerSocket serverSocket = new ServerSocket(포트번호); //서버소켓 선언
Scoket socket = serverSocket.accept(); //서버 소켓 대기
socket.getInputStream() // 읽기
socket.getOutputStream() // 쓰기
서버는 하나의 클라이언트와만 접촉하는 것이 아니므로 보통 무한 루프에서 받는다. 혹은 스레드를 사용해..
소켓은 하나의 클라이언트마다 한개의 소켓을 생성해 접근한다.
클라이언트의 소켓 메소드
Socket socket = new Socket(IP주소, 포트번호); //소켓 열기
socket.getInputStream(); //읽기
socket.getOutputStream(); //쓰기
socket.close(); //닫기
간단한 서버 예제
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; public class ServerExam { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8000); // 서버소켓 선언 while (true) { System.out.println("클라이언트 접속 대기 중..."); Socket socket = serverSocket.accept(); // 서버소켓으로부터 소켓 객체 가져오기 System.out.println(socket.getInetAddress() + "가 접속되었습니다."); // InputStream inputStream = socket.getInputStream(); // InputStreamReader inputStreamReader = new // InputStreamReader(inputStream); // BufferedReader bufferedReader = new BufferedReader(inputStreamReader); // 위의 세줄을 한줄로 표현 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 클라이언트로부터 메시지 입력받음 String clientMessage = bufferedReader.readLine(); // 입력받은 내용을 서버 콘솔에 출력 System.out.println("클라이언트가 보내온 내용 : " + clientMessage); // 클라이언트에게 보내기 위한 준비 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bufferedWriter.write("JAVA의 세계에 오신 것을 환영합니다!"); bufferedWriter.newLine(); //readLine()으로 읽으므로 한줄끝을 알림 bufferedWriter.flush(); //PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true); //printWriter.println("JAVA의 세계에 오신 것을 환영합니다!!"); socket.close();//접속 종료 } } catch (Exception e) { e.printStackTrace(); } } }
간단한 클라이언트 예제
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; public class ClientExam { public static void main(String[] args) { try { Socket socket = new Socket("127.0.0.1", 8800); // 서버에게 보내기 위한 준비 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bufferedWriter.write("안녕하세요!"); bufferedWriter.newLine(); //readLine()으로 읽기 때문에 개행 추가 bufferedWriter.flush(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 서버부터 메시지 입력받음 String clientMessage = bufferedReader.readLine(); // 입력받은 내용을 서버 콘솔에 출력 System.out.println("서버가 보내온 내용 : " + clientMessage); socket.close();//접속 종료 } catch (Exception e) { e.printStackTrace(); } } }
채팅 서버 예제
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import javax.swing.JFrame; public class ChatExam { // 프레임 선언 private JFrame jFrame = new JFrame("채팅"); //서버 소켓 및 소켓 선언 private ServerSocket serverSocket; private Socket socket; //소켓들을 담을 ArrayList 선언 private ArrayList<Socket> socketList = new ArrayList<Socket>(); public ChatExam() { // 프레임 크기 및 보이기 설정 jFrame.setSize(500, 400); jFrame.setVisible(true); // swing에만 있는 X버튼 클릭시 종료 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try { serverSocket = new ServerSocket(8000); // 서버소켓 선언 while( true ) { //소켓이 생성될 때까지 대기 socket = serverSocket.accept(); // 소켓이 생성되면, if( socketList.add(socket) ) { new Thread() { @Override public void run() { BufferedReader bufferedReader = null; try { // 이 내용을 while문 안에 넣었을 때 문제가 생겼다. // 다름아닌 계속해서 소켓을 새로 생성하는 문제였는데, // 다행히 클라이언트는 소켓이 변화되지 않는다. 따라서 // 문제가 없었지만, 서버에서는 소켓이 새로 생성될 때마다 달라졌으므로 문제가 // 커졌다. bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); while( true ) { // 클라이언트로부터 메시지 입력받음 String clientMessage = bufferedReader.readLine(); // 입력받은 메시지가 길이가 0 이상이면, if( clientMessage.trim().length() > 0 ) { //클라이언트 하나로부터 전달받은 메시지를 전파 ChatExam.this.spreadMessage(clientMessage); } if( clientMessage.contains("님이 퇴장하셨습니다. ")) { System.out.println("퇴장했을 경우 버퍼리더 정리"); break; } } } catch (Exception e) { System.out.println(e + "=>server run"); } finally { // 읽어오기 종료 try { bufferedReader.close(); } catch (IOException e) { System.out.println(e + "=> "); } } } }.start(); // 스레드 실행 } } } catch (Exception e) { System.out.println(e); } } //메시지를 전파하는 메소드 public void spreadMessage(String message) { for( int i = socketList.size() - 1 ; i > -1 ; i-- ) { // 클라이언트에게 보내기 위한 준비 try { if( !socketList.get(i).isClosed() ) { BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socketList.get(i).getOutputStream())); bufferedWriter.write(message); bufferedWriter.newLine(); bufferedWriter.flush(); } else { socketList.remove(i); } } catch (Exception e) { System.out.println("소켓 에러"); } } } public static void main(String[] args) { new ChatExam(); } }
채팅 클라이언트 예제
import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.Socket; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; public class ChatClient { // 프레임 선언 JFrame jFrame = new JFrame("채팅"); // Swing에서의 텍스트 영역.. 스크롤바가 존재하지 않는다. JTextArea textArea = new JTextArea("", 0, 0);// 스크롤바 없음 // Swing에서 스크롤바를 넣기 위해 아래와 같이 사용한다. JScrollPane jScrollPane = new JScrollPane(textArea);// 스클롤바 만들기 // 내용을 입력할 입력창 JTextField inputText = new JTextField(); //소켓 Socket socket; //이름 String name; public ChatClient() { textArea.setEnabled(false); textArea.setFocusable(false); // 텍스트 영역 추가 jFrame.add(jScrollPane, "Center"); jFrame.add(inputText, "South"); // 프레임 크기 및 보이기 설정 jFrame.setSize(500, 400); jFrame.setVisible(true); // swing에만 있는 X버튼 클릭시 종료 jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jFrame.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { super.windowClosing(e); sendMessage(name + "님이 퇴장하셨습니다. "); } }); try { socket = new Socket("127.0.0.1", 8000); } catch (Exception e) { System.out.println("클라이언트 소켓 생성 에러"); } //이름설정 do { name = JOptionPane.showInputDialog(this, "이름은?"); }while(name == null || name.length() < 2); sendMessage(name + "님이 입장하셨습니다."); jFrame.setTitle(name + "님의 채팅창"); new Thread() { @Override public void run() { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); while ( true ) { // 클라이언트로부터 메시지 입력받음 String clientMessage = bufferedReader.readLine(); if( clientMessage != null && clientMessage.trim().length() > 0 ) { textArea.append(clientMessage + "\n"); textArea.setCaretPosition(textArea.getText().length()); } } } catch (Exception e) { System.out.println(e+"=>clinet run"); e.printStackTrace(); } finally { //읽어오기 종료 try { bufferedReader.close(); textArea.append("\n**읽어오기 종료**\n"); } catch (IOException e) { System.out.println(e); } } } }.start(); // 스레드 실행 inputText.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { if( e.getKeyCode() == 10 ) { if( inputText.getText().trim().length() > 0 ) { sendMessage(name + " : " + inputText.getText().trim()); inputText.setText(null); } } } }); } public void sendMessage(String message) { try { // 클라이언트에게 보내기 위한 준비 BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); bufferedWriter.write(message); bufferedWriter.newLine(); bufferedWriter.flush(); } catch (Exception sendError) { System.out.println("메시지 전송 에러 : " + sendError); } } public static void main(String[] args) { new ChatClient(); } }