소켓 프로그래밍: TCP와 UDP(3)

2022. 5. 2. 11:30·자바/네트워킹

3-6. 소켓 프로그래밍을 이해하기 위한 예제(6)

: 채팅 프로그램을 만드는 예제이다.

 

( 아래는 서버 프로그램이다. )

package Networking;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Exercise011 {
	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Socket socket = null;

		try {
			// 서버소켓을 생성하여 7777번 포트와 결합(bind)시킨다.
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 준비되었습니다.");

			socket = serverSocket.accept();

			Sender   sender   = new Sender(socket);
			Receiver receiver = new Receiver(socket);

			sender.start();
			receiver.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	} // main
} // class

class Sender extends Thread {
	Socket socket;
	DataOutputStream out;
	String name;

	Sender(Socket socket) {
		this.socket = socket;
		try {
			out = new DataOutputStream(socket.getOutputStream());
			name = "["+socket.getInetAddress()+":"+socket.getPort()+"]";
		} catch(Exception e) {}
	}

	public void run() {
		Scanner scanner = new Scanner(System.in);
		while(out!=null) {
			try {
				out.writeUTF(name+scanner.nextLine());		
			} catch(IOException e) {}
		}
	} // run()
}

class Receiver extends Thread {
	Socket socket;
	DataInputStream in;

	Receiver(Socket socket) {
		this.socket = socket;
		try {
			in = new DataInputStream(socket.getInputStream());
		} catch(IOException e) {}

	}

	public void run() {
		while(in!=null) {
			try {
				System.out.println(in.readUTF());
			} catch(IOException e) {}
		}
	} // run
}

 

 

( 아래는 클라이언트 프로그램이다. )

 

package Networking;

import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;

public class Exercise012 {
	public static void main(String[] args) {
		try {
			String serverIp = "127.0.0.1";
            
			// 소켓을 생성하여 연결을 요청한다.
			Socket socket = new Socket(serverIp, 7777); 

			System.out.println("서버에 연결되었습니다.");
			Sender sender = new Sender(socket);
			Receiver receiver = new Receiver(socket);

			sender.start();
			receiver.start();
		} catch(ConnectException ce) {
			ce.printStackTrace();
		} catch(IOException ie) {  
			ie.printStackTrace();
		} catch(Exception e) {
			e.printStackTrace();  
		}  
	} // main
} // class

 

 

 

 

3-7. 소켓 프로그래밍을 이해하기 위한 예제(7)

: 멀티 채팅 프로그램을 구현한 예제이다.

 

( 아래는 서버 프로그램이다. )

package Networking;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;

public class Exercise013 {
	HashMap clients;
	
	Exercise013() {
		clients = new HashMap();
		Collections.synchronizedMap(clients);
		//동기화처리
	}
	
	public static void main(String args[]) {
		new Exercise013().start();
	} 

	public void start() {
		ServerSocket serverSocket = null;
		Socket socket = null;

		try {
			serverSocket = new ServerSocket(3333);
			System.out.println("서버가 시작되었습니다.");

			while(true) {
				socket = serverSocket.accept();
				System.out.println("["+socket.getInetAddress()+":"+socket.getPort()+"]"+"에서 접속하였습니다.");
				ServerReceiver thread = new ServerReceiver(socket);
				thread.start();
			}
		} catch(Exception e) {
			e.printStackTrace();
		}
	} // start()

	void sendToAll(String msg) {
		Iterator it = clients.keySet().iterator();
		
		while(it.hasNext()) {
			try {
				DataOutputStream out = (DataOutputStream)clients.get(it.next());
				out.writeUTF(msg);
			} catch(IOException e){}
		} // while
	} // sendToAll
	
	class ServerReceiver extends Thread {
		Socket socket;
		DataInputStream in;
		DataOutputStream out;

		ServerReceiver(Socket socket) {
			this.socket = socket;
			try {
				in  = new DataInputStream(socket.getInputStream());
				out = new DataOutputStream(socket.getOutputStream());
			} catch(IOException e) {}
		}

		public void run() {
			String name = "";
			try {
				name = in.readUTF();
				sendToAll("#"+name+"님이 들어오셨습니다.");

				clients.put(name, out);
				System.out.println("현재 서버접속자 수는 "+ clients.size()+"입니다.");

				while(in!=null) {
					sendToAll(in.readUTF());
				}
			} catch(IOException e) {
				// ignore
			} finally {
				sendToAll("#"+name+"님이 나가셨습니다.");
				clients.remove(name);
				System.out.println("["+socket.getInetAddress() +":"+socket.getPort()+"]"+"에서 접속을 종료하였습니다.");
				System.out.println("현재 서버접속자 수는 "+ clients.size()+"입니다.");
			} // try
		} // run
	} // ReceiverThread
} // class

( readUTF()에서 IOException을 발생시켜 클라이언트 나간 것을 확인한다. )

 

 

( 아래는 클라이언트 프로그램이다. )

package Networking;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.net.Socket;
import java.util.Scanner;

public class Exercise014 {
	public static void main(String args[]) {
		if(args.length!=1) {
			System.out.println("USAGE: java TcpIpMultichatClient 대화명");
			System.exit(0);
		}

		try {
			String serverIp = "127.0.0.1";
            // 소켓을 생성하여 연결을 요청한다.
			Socket socket = new Socket(serverIp, 7777); 
			System.out.println("서버에 연결되었습니다.");
			Thread sender   = new Thread(new ClientSender(socket, args[0]));
			Thread receiver = new Thread(new ClientReceiver(socket));

			sender.start();
			receiver.start();
		} catch(ConnectException ce) {
			ce.printStackTrace();
		} catch(Exception e) {}
	} // main

	static class ClientSender extends Thread {
		Socket socket;
		DataOutputStream out;
		String name;

		ClientSender(Socket socket, String name) {
			this.socket = socket;
			try {
				out = new DataOutputStream(socket.getOutputStream());
				this.name = name;
			} catch(Exception e) {}
		}

		public void run() {
			Scanner scanner = new Scanner(System.in);
			try {
				if(out!=null) {
					out.writeUTF(name);
				}	

				while(out!=null) {
					out.writeUTF("["+name+"]"+scanner.nextLine());					}
			} catch(IOException e) {}
		} // run()
	} // ClientSender

	static class ClientReceiver extends Thread {
		Socket socket;
		DataInputStream in;

		ClientReceiver(Socket socket) {
			this.socket = socket;
			try {
				in = new DataInputStream(socket.getInputStream());
			} catch(IOException e) {}
		}

		public void run() {
			while(in!=null) {
				try {
					System.out.println(in.readUTF());
				} catch(IOException e) {}
			}
		} // run
	} // ClientReceiver
} // class

 

이클립스 출력문
이클립스 출력문
cmd 출력문

( 아이디어는 아래와 같다. )

 

< 서버 >

메서드 설명
메인 클래스 생성자() HashMap의 초기화와 HashMap 동기화
main() 생성자 실행과 start() 함수 호출
start() 서버 구동을 위한 작업과 다중 클라이언트를 위한 무한반복문 작업(ServerReceiver)
ServerReceiver 클래스 생성자() 소켓과 DataInputStream과 DataOutputStream 초기화
run() 다중 클라이언트를 위해 쓰레드 구현
sendToAll() 다중 클라이언트에게 메시지를 보내는 메서드(동기화를 이용)



< 클라이언트 >

메서드 설명
main() 이름을 입력했는지 확인과 서버연결, Sender와 Receiver의 쓰레드 실행
 Main 클래스의 static Sender 클래스 Socket, DataOutputStream을 초기화
Sender의 run() 초기 ServerReceiver 클래스에게 자신의 이름을 보냄. 그리고 나서
클라이언트의 채팅할 내용을 사용자 입력한 것을 읽어 서버에게 보냄
Main 클래스의 static Receiver 클래스 Socket, DataInputStream, 이름을 초기화
Receiver의 run() 다른 클라이언트의 내용이나 서버의 내용을 받아서 출력

 

 

 

 

다음장

소켓 프로그래밍: TCP와 UDP(4) (tistory.com)

 

저작자표시 (새창열림)

'자바 > 네트워킹' 카테고리의 다른 글

소켓 프로그래밍: TCP와 UDP(4)  (0) 2022.05.02
소켓 프로그래밍: TCP와 UDP(2)  (0) 2022.05.02
소켓 프로그래밍: TCP와 UDP(1)  (0) 2022.05.01
네트워킹(Networking) (2) - URL, URLConnection  (0) 2022.04.30
네트워킹(Networking) (1) - InetAddress  (0) 2022.04.30
'자바/네트워킹' 카테고리의 다른 글
  • 소켓 프로그래밍: TCP와 UDP(4)
  • 소켓 프로그래밍: TCP와 UDP(2)
  • 소켓 프로그래밍: TCP와 UDP(1)
  • 네트워킹(Networking) (2) - URL, URLConnection
백_곰
백_곰
  • 백_곰
    친절한 코딩
    백_곰
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘 (with JAVA)
        • 기본 알고리즘
        • 완전 탐색
        • 분할 정복 알고리즘
        • 동적 계획법
        • 탐욕법
        • 코딩 테스트 기출 문제
        • 코드트리 조별과제
      • 백준 (with JAVA)
        • 완전 탐색
        • 분할 정복
        • 그 외
      • 자바
        • 개발 환경 구축하기
        • 팁
        • 기본적인 개념
        • 컬렉션 프레임워크
        • 프로세스와 쓰레드
        • 지네릭스
        • 람다식
        • 스트림
        • 입출력 IO
        • 네트워킹
        • 열거형(enums)
        • java.lang 패키지
        • java.time 패키지
        • 유용한 클래스들
        • 형식화 클래스들
      • 안드로이드 with 자바
        • 응용 문제들
        • 자잘한 문제들
        • 오류 보고서
  • 블로그 메뉴

    • 링크

    • 공지사항

    • 인기 글

    • 태그

      ServerSocket
      자바 개념
      java.lang패키지
      TCP 소켓 프로그래밍
      스트림
      람다식
      유용한 클래스
      map()
      코딩테스트
      소켓 프로그래밍
      file
      제자리 정렬
      문자 기반 스트림
      코드트리
      중간연산
      serializable
      안드로이드 스튜디오
      다형성
      선택 정렬
      snail
      코딩트리조별과제
      안정 정렬
      불안정 정렬
      java.time 패키지
      outputstream
      Arrays
      InputStream
      Collections Framework
      역직렬화
      알고스팟
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    백_곰
    소켓 프로그래밍: TCP와 UDP(3)
    상단으로

    티스토리툴바