01-03에서 마지막에 한 작업이 관리자 계정으로 접속하는 것이다.


먼저 파일을 저장하기 전에 UTF-8 인코딩 설정을 해주자.





화면 상단 바의 도구 - 환경설정 - 환경 - 인코딩 설정을 UTF-8로 바꾸면 된다.


그리고나서 메모장 처럼 빈 화면을 그 상태에서 저장버튼을 눌러


마음에 드는 곳에 위치를 설정하자.




다음으로 코드, 쿼리문을 직접 입력해보자


SQL의 코드들은 질의문, 쿼리문이라고 한다.


코드의 설명은 주석(--)으로 설명한다.


-- comment(주석)

-- 권한주고 사용자 만들고 삭제하고 등등은 SYS 계정, 관리자 계정으로만 가능하다.
-- 잘못 준다면 DB 통째로 꼬이고 망가지게 된다.
-- 초보가 다루기에는 무리가 있으므로 만약 입사하자마자 다루라고 시키면 조심해야 한다.

-- 사용자 생성
-- CREATE USER [유저 이름] IDENTIFIED BY [비밀 번호];
-- 정해져있는 문구는 보통 대문자, 변경이 가능한 문구는 보통 소문자를 사용함
-- 구지 그러지 않아도 되지만 일반적으로 이렇게 작성하여 알아보기 쉽게 한다.
-- 문구를 작성 한 후 Ctrl + Enter를 누르면 문구가 실행된다.
-- 드래그 하여 여러 구문을 한번에 실행 시킬 수 있다.
CREATE USER dba_user IDENTIFIED BY pass;
CREATE USER web_user IDENTIFIED BY pass;
CREATE USER user02 IDENTIFIED BY pass;

-- 유저의 비밀번호 변경
-- ALTER USER [유저 이름] IDENTIFIED BY [비밀 번호];
ALTER USER user02 IDENTIFIED BY pass;

-- 유저 확인
-- SELECT [가져올 항목] FROM [특정 테이블];
SELECT USERNAME FROM DBA_USERS;
-- *은 ALL을 의미
SELECT * FROM DBA_USERS;

-- 유저 삭제
-- DROP USER [유저 이름]
DROP USER user02;

-- 권한 부여(권한이 여러개일 경우 ','로 구분)
-- GRANT [권한, 권한, ...] TO [대상 유저]
GRANT CONNECT, RESOURCE, DBA TO web_user;
GRANT CONNECT, DBA TO dba_user;

-- 권한 회수
-- REVOKE [권한] FROM [대상 유저]
REVOKE DBA FROM web_user;

-- 권한 확인
SELECT * FROM DBA_ROLE_PRIVS;
SELECT * FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'WEB_USER';


-- TABLE SPACE 권한 생성
GRANT UNLIMITED TABLESPACE TO web_user;


다시 한번 쓰지만 DB의 유저를 생성하는 컨트롤은 DB관리자가 따로 하는거지


지금 한 작업은 연습용으로 초기에 한 것이다.


sys계정으로 함부로 무언가 하면 DB가 날아갈 수 있으므로 주의

전의 과정을 수행해서 설치를 완료했다면 이제 실행해보자


SQLdeveloper을 압축 해제할 때 바로가기를 만들어뒀던 아이콘을 실행시켜보자.





위와 같은 창이 하나 뜨는데 jdk 경로를 설정해달라는 것이다.


설치한 경로를 찾아 폭더를 선택해주자








실행하고 중간에 전에 사용한 환경설정을 가져다가 쓸거냐고 물어보는데 처음 설치자는 아니요를 누르면 된다.





첫 화면이 뜨면 좌측의 초록색 + 버튼을 눌러 DB를 새로 만든다.


창이 뜨면 접속 이름, 사용자 이름, 비밀번호, 등 설정을 마치면 된다.


그리고 롤(L) 은 SYSDBA로 설정하자.


sys / 1111 은 관리자 계정이므로 중요하기 때문에 색깔을 빨간색으로 지정하였다.


마지막으로 아래의 테스트를 눌러 잘 되는지 확인하고 접속을 누르면 된다.





원래는 sys를 잘못건드리면 전부 날아가버리는 사태가 벌어질 수 있으므로 실무에서 조심하자.


SID는 DataBase, DataSpace와 같은 의미로 이해하면 된다.




설치 시 실수하면 지우고 다시 설치해야 하고


지울때 레지스트리 설정 및 남은 파일 등 여러가지 할 작업이 많아 진다.


한 번 설치 할 때 제대로 설치 하자.


먼저 SQL Developer의 압축을 해제, SQL Developer은 설치형이 아니라서 실행파일을 누르면 바로 사용이 가능하다.


필자는 D드라이브에 해제 해 놓았다.





압축을 풀고 안에 있는 sqldeveloper.exe의 바로가기를 마음에 드는곳에 생성하면 끝







다음으로는 Oracle Database의 압축을 해제하는데 이건 설치형이기 때문에 


압축을 해제하고 나온 Setup을 클릭







진행하다가 비밀번호, Password 입력하라고 나오는데


이 비밀번호는 관리자 비밀번호로 정말 중요하다.


만약 까먹는다면 재설치해야 하므로 꼭 기억해두자


저는 1111으로 입력하겠습니다.



Next를 눌러 경로 설정이 나오고 맘에 드는 곳으로 설치 경로를 잡은 후에


진행하다보면 위와 같은 Setting을 알려주는 텍스트가 뜨는데 따로 메모장에 기록해두자.


그 후 Install을 눌러 설치를 진행하자.


시간이 조금 걸리지만 멈춘게 아니므로 계속 기다리자






설치가 다 되면 윈도우키를 눌러 Run SQL Command Line 아이콘을 찾아서 실행해서 잘 설치 됫는지 연결이 되 있는지 확인



CONN sys/1111 as sysdba


를 입력하면 연결이 잘 됫는지 표시된다.


sys/1111 은 관리자계정/관리자비밀번호를 의미한다.







Oracle Database는 따로 실행하지 않아도 시스템 시작 시 자동으로 시작된다.


그러므로 부팅시간이 늘어나고 평소의 리소스도 잡아먹게 된다.


그래서 수동으로 켜고 끄게끔 설정한다.


화면 하단 작업 바에 우클릭하여 작업 관리자를 킨다.




서비스탭의 OracleServiceXE를 오른쪽 클릭하여 서비스 열기를 누른다.





서비스 리스트에서 OracleServiceXE를 찾아 우클릭 + 속성을 눌러


시작 유형을 수동으로 변경하면 된다.





앞으로 시스템 부팅 시 같이 켜지지 않을 것이다.


다시 윈도우키를 누르고 Start Database, Stop Database를 찾아보자.


Start Database, Stop Database는 말그대로 DB를 껏다 킬 수 있다.


이제부터 수동으로 껏다 키면 된다.



윈도우 8에서는 윈도우키를 누르면 이렇게 나온다.


Start Stop 실행 화면















JDK, Eclipse와는 다르게 Oracle Database는 계정이 필요하다.


먼저 https://www.oracle.com 로 접속한다.




오라클의 페이지는 자주 바뀌기 때문에 알아서 잘 찾아가야함. 글 작성 시기인 18.10.01과 다를 수 있다.


페이지 상단의 sign In에 마우스를 올려 Create an account를 눌러 요구하는대로 입력해서 가입한다.


로그인을 하고 메인 화면에서 다음과 같이 따라가보자.





페이지는 시간이 지나면 바뀌므로 잘 찾아보아야 할 수 있다.


Menu - Developers - Downloads



페이지는 시간이 지나면 바뀌므로 잘 찾아보아야 할 수 있다.


Download를 누른 후 스크롤을 아래로 내려 Database 11g Express Edition을 클릭, db는 전부 유료이고 Express Edition은 학생용, 교육용으로 배포


Express Edition을 상업용 목적으로 사용하면 고소장 날라와도 할 말 없다..






Accept를 누르고 자신의 운영체제에 맞는 버젼을 다운로드


다음으로는 SQL Developer 다운로드


메인에서 Download를 누르고 들어온 페이지에서 SQL Developer를 찾아보자




SQL Developer를 눌러 자신의 버젼에 맞는 파일을 다운받는데




예전에 Eclipse를 설치할 때 JDK 1.8을 다운받았다.


그렇다면 jdk 8 버젼이므로 Windows 64-bit with JDK 9 Included말고 


그 아래 항목을 선택해 다운로드 하자.













먼저 화면 좌측 상단 메뉴바




File - Import





General의 Existing Projects into Workspace 선택





Select archive file을 선택하고 Browse..를 눌러


다운받은 Workspace zip파일을 선택하면 리스트에 프로젝트가 나온다.


원하는 프로젝트를 선택하고 Finish를 눌러 Import를 마친다.


본 블로그에서 사용한 Workspace는 아래와 같다.


Java.zip

JavaFX.zip


Java - 게시글 분류 중 개념 및 코딩


JavaFX - 게시글 분류 중 JavaFX


Workspace를 zip파일로 Export하여 공유하는법







화면 좌측 상단의 메뉴바 - File - Export 클릭






리스트 맨 위의 General의 Archive File 선택






화면 좌측의 포함할 프로젝트를 선택 한 후 


To archive file - zip파일이 저장될 경로를 선택해주고 Finish가 활성화 되면 끝


본 블로그에서 사용한 Workspace는 아래와 같다.


Java.zip

JavaFX.zip



Java - 게시글 분류 중 개념 및 코딩


JavaFX - 게시글 분류 중 JavaFX

네트워크를 통해 파일을 전송하는것은 Stream에서 파일 전송의 활용이라고 보면 된다.


Stream을 통해서 읽어온 데이터를 그대로 전송하면 된다.


네트워크 부분은 대부분 비슷하기 때문에 설명은 많이 적지 않고 코드의 주석을 통해 설명




Receiver 클래스



package chap12.exam07.file;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
// 직접 만들어본 리시버
public class Receiver {

	public static void main(String[] args) throws Exception {
		// 데이터를 받으려면 항시 대기하여야 하는데 while문으로 묶어버리면
		// 아래의 코드가 작동되지 않으므로 따로 스레드를 만들어야함
		String path = "C:/img/temp2/aaa.pdf";
		// 1. DatagramSocket 생성
		DatagramSocket socket = new DatagramSocket(5001);
		FileOutputStream fos = new FileOutputStream(path);
		
		Thread th = new Thread(){
			@Override
			public void run() {
				// 2. DatagramPacket 준비 (한번에 받은 메시지 크기)
				DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
				while(true) {
					try {
						socket.receive(packet);		// 3. 데이터 수신
						byte[] character = packet.getData();
						fos.write(character);
					} catch (IOException e) {
						e.printStackTrace();
						break;
					}
				}
			}
		};
		th.setDaemon(true); // main이 끝나면 같이 죽도록 설정
		th.start(); // 스레드 실행
		// 5. 자원 정리
		Thread.sleep(10000);
		socket.close(); // 소켓을 닫고
		// 종료		
	}

}


Main FileReceiver



package chap12.exam07.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class FileReceiver {

	public static void main(String[] args) throws Exception {
		// 1. 서버소켓 생성
		ServerSocket server = new ServerSocket(7777);

		while(true) { // 대기
			System.out.println("요청 대기중...");
			// 2. 연결 수락
			Socket socket = server.accept();
			System.out.println("수락");

			Thread th = new Thread() {

				@Override
				public void run() {
					try {
						// 3. 파일 위치 지정
						String path = "C:/img/temp2/";
						
						// 4. 스트림 준비
						BufferedInputStream bis = new BufferedInputStream(socket.getInputStream()); // 파일명 받기
						DataInputStream dis = new DataInputStream(bis);
						path += dis.readUTF();
						System.out.println(path);
						FileOutputStream fos = new FileOutputStream(path);  // 파일 받아오기
						BufferedOutputStream bos = new BufferedOutputStream(fos);

						// 5. 읽기 -> 쓰기
						// 배열로 받을 경우 다른 IP로 전송 시 파일이 깨질 수 있음
						byte[] source = new byte[1024];
						while(dis.read(source) != -1) {
							bos.write(source);
						}
						
//						int data;
//						while((data = dis.read() != -1)) {
//							bos.write(data);
//						}
						bos.flush();
						System.out.println("다운로드 완료");
						bos.close();
						fos.close();
						bis.close();
						dis.close();
						socket.close();
					}catch (Exception e) {
						System.out.println(e.toString());
					}
				}
			};
			th.start();
		}
	}

}


Sender 클래스



package chap12.exam07.file;

import java.io.FileInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class Sender { // 직접 만들어본 sender

	public static void main(String[] args) throws Exception {
		String pathInput = "C:/img/10multi.pdf";
		FileInputStream fis = new FileInputStream(pathInput);
		// 1. DatagramSocket 생성
		DatagramSocket socket = new DatagramSocket();
		int i = 0;
		byte[] buffer = new byte[1024];
		
		while(fis.read(buffer)!=-1) { // -1 == EOF
			// 4. 내보내기
			DatagramPacket packet = new DatagramPacket(buffer, buffer.length, new InetSocketAddress("localhost", 5001));
			socket.send(packet);
			i++;
			System.out.println("파일 복사중... " + i);
		}


		fis.close();
		socket.close();

	}

}


Main FileSender



package chap12.exam07.file;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.net.Socket;

public class FileSender {

	public static void main(String[] args) throws Exception {
		// 1. 파일 위치
		String path = "C:/img/10multi.pdf";
		int i = 0;
		// 2. 스트림 준비 + 소켓(스트림)
		try(
		FileInputStream fis = new FileInputStream(path);
		BufferedInputStream bis = new BufferedInputStream(fis);
		Socket socket = new Socket("여기에 IP를 입력해야 정상적으로 동작해요">", 7777);
		BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
		DataOutputStream dos = new DataOutputStream(bos);
		){
			// 3. 읽어오기 -> 전송(파일 바이너리 + 파일 명)
			String[] name = path.split("/");
			dos.writeUTF(name[name.length-1]); // -1번방의 내용을 전송
			dos.flush();
			
			// 파일 바이너리 전송
			byte[] source = new byte[1024];
			while(bis.read(source) != -1 ) {  // 한번의 루프로 1024바이트(1kb) 전송
				dos.write(source);
				// 전송 진행율 표시를 어떻게 할 것인가????
				i++;
				System.out.println("파일 전송중..." + i + " / " + source.length);
			}
			dos.flush();
			System.out.println("전송 완료...!");
			
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}

}


File Sender의 19번째 줄에 접속할 대상의 IP를 입력해주어야 한다.


그리고 서버는 이클립스에서 실행하고


클라이언트를 따로 실행해야 하는데


https://qdgbjsdnb.tistory.com/79 를 참조하여 cmd에서 클라이언트를 작동해보자.





'개념 및 코딩 > 10.네트워크' 카테고리의 다른 글

[JAVA]10-06.UDP, Datagram  (0) 2018.09.27
[JAVA]10-05.N:M MultiChat Server, Client  (2) 2018.09.27
[JAVA]10-04.1:1 Chat Server, Client  (0) 2018.09.27
[JAVA]10-03.Echo Server, Client  (0) 2018.09.27
[JAVA]10-02.TCP Server, Client  (0) 2018.09.27

UDP는 TCP와 달리 DatagramSocket과 DatagramPacket을 사용한다.


TCP와의 차이점으로는 일방적인 전송을 하고 확인 작업이 없기 때문에 속도가 빠르지만


정확도가 낮다




Server가 될 Receiver


package chap12.exam06.udp;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receiver {

	public static void main(String[] args) throws Exception {
		// 데이터를 받으려면 항시 대기하여야 하는데 while문으로 묶어버리면
		// 아래의 코드가 작동되지 않으므로 따로 스레드를 만들어야함

		// 1. DatagramSocket 생성
		DatagramSocket socket = new DatagramSocket(5001);

		Thread th = new Thread(){

			@Override
			public void run() {
				// 2. DatagramPacket 준비 (한번에 받은 메시지 크기)
				DatagramPacket packet = new DatagramPacket(new byte[100],  100);
				while(true) {
					try {
						socket.receive(packet);		// 3. 데이터 수신
						byte[] character = packet.getData();
						String data = new String(character,  "UTF-8").replace('\0', ' ');
						System.out.println(data);		// 4. 받은 데이터 출력
					} catch (IOException e) {
						e.printStackTrace();
						break;
					}
				}
			}
		};
		th.setDaemon(true); // main이 끝나면 같이 죽도록 설정
		th.start(); // 스레드 실행
		// 5. 자원 정리
		Thread.sleep(10000);
		socket.close(); // 소켓을 닫고
		// 종료		
	}

}


Client가 될 Sender


package chap12.exam06.udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

public class Sender {

	public static void main(String[] args) throws Exception {
		// 1. DatagramSocket 생성
		DatagramSocket socket = new DatagramSocket();
		// 2. 보낼 메시지 준비
		for(int i = 1; i <= 3; i++) {
			String msg = "data_" + i;
			byte[] arr = msg.getBytes();
			// 3. DatagramPacket으로 전송
			DatagramPacket packet = new DatagramPacket(arr,  arr.length, new InetSocketAddress("localhost", 5001));
			socket.send(packet);
		}

		// 4. 자원 반납
		socket.close();
		
	}

}



서버는 이클립스에서 실행하고


클라이언트를 따로 실행해야 하는데


https://qdgbjsdnb.tistory.com/79 를 참조하여 cmd에서 클라이언트를 작동해보자.



1:1 채팅을 조금 바꾼 다대다, N:M 멀티 채팅이다.


전과 다른점으로는 클라이언트와 서버에 사용할 Receiver, Sender 따로 있는 점이다.





서버 기능을 가지고 있는 ServerManager 클래스


package chap12.exam05.multichat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

public class ServerManager extends Thread {
	Socket socket;
	DataInputStream in;
	DataOutputStream out;
	// 서버이기에 in 먼저 일어남
	
	public ServerManager(Socket socket) throws IOException {
		this.socket = socket;
		in= new DataInputStream(socket.getInputStream());
		sendMsg(socket.getPort() + "님이 입장 하였습니다.");
	}

	@Override
	public void run() { // 서버는 메시지를 감지해야 하므로 in을 이용
		while(in != null) {
			try {
				sendMsg(socket.getPort()+"> " + in.readUTF());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			in.close();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void sendMsg(String msg) throws IOException { // MultiServer의 List에서 소켓 리스트를 받아옴
		System.out.println(msg);
		for(Socket soc : MultiServer.list) {
			out = new DataOutputStream(soc.getOutputStream());
			out.writeUTF(msg);
			out.flush();
		}
	}


}




ServerManager를 불러오는 MultiServer


package chap12.exam05.multichat;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

public class MultiServer {
	static ArrayList<Socket> list = new ArrayList<>();
	
	public static void main(String[] args) throws IOException {
		
		ServerManager manager;
		Socket socket;
		ServerSocket server = new ServerSocket(5252);
		System.out.println("서버 실행 중");
		
		while(true) {
			socket = server.accept(); // 소켓을 기다림
			list.add(socket); // 추가
			manager = new ServerManager(socket);
			manager.start();
		}
	}

}



다음으로는 Client에 필요한 클래스와 메인 클라이언트


Sender


package chap12.exam05.multichat;

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

public class ClientSender extends Thread {
	Socket socket;
	DataOutputStream out;
	
	public ClientSender(Socket socket) throws IOException {
		// 초기화와 동시에 스트림도 잡아주면 효율적
		this.socket = socket;
		out = new DataOutputStream(socket.getOutputStream());
		// socket.getOutputStream을 그대로 형변환 해도 된다.
	}

	@Override
	public void run() {
		while(out != null) {
			System.out.print("당신>");
			Scanner scan = new Scanner(System.in);
			
			try {
				out.writeUTF(scan.nextLine());
				out.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}



Receiver



package chap12.exam05.multichat;

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

public class ClientReceiver extends Thread {
	Socket socket;
	DataInputStream in;
	
	public ClientReceiver(Socket socket) throws IOException {
		this.socket = socket;
		in = new DataInputStream(socket.getInputStream());
		// Sender와 크게 차이 없음
	}

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

}



실질적으로 동작할 Main MultiClient



package chap12.exam05.multichat;

import java.net.Socket;

public class MultiClient {

	public static void main(String[] args) throws Exception {
		Socket socket = new Socket("여기에 IP를 입력해야 정상적으로 동작해요", 5252);
		System.out.println("연결 성공");
		ClientReceiver receiver = new ClientReceiver(socket);
		ClientSender sender = new ClientSender(socket);
		
		receiver.start();
		sender.start();
	}

}




8번째 줄에 접속할 대상의 IP를 입력해주어야 하고 1개의 컴퓨터로 테스트 할 경우


대상 Server가 자기 자신이므로 자신의 IP를 입력하면 된다.


그리고 서버는 이클립스에서 실행하고


클라이언트를 따로 실행해야 하는데


https://qdgbjsdnb.tistory.com/79 를 참조하여 cmd에서 클라이언트를 작동해보자.



'개념 및 코딩 > 10.네트워크' 카테고리의 다른 글

[JAVA]10-06.File Sender, Receiver  (0) 2018.09.27
[JAVA]10-06.UDP, Datagram  (0) 2018.09.27
[JAVA]10-04.1:1 Chat Server, Client  (0) 2018.09.27
[JAVA]10-03.Echo Server, Client  (0) 2018.09.27
[JAVA]10-02.TCP Server, Client  (0) 2018.09.27

이번에는 1:1 채팅 프로그램으로


채팅을 한번 하고 끝나지 않기 위해서는 반복문을 돌려야만 한다.


또한 통신 기능 외의 작업이 같이 돌아가야 하기 때문에 Thread를 이용한다.






메시지를 받을 서버 Receiver 클래스



package chap12.exam04.chat;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;

public class Receiver extends Thread {
	private Socket socket = null;

	public Receiver(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			// 4. InputStream으로 보내온 메시지를 받는다.
			InputStream is = socket.getInputStream(); // 핵심
			BufferedInputStream bis = new BufferedInputStream(is);
			InputStreamReader reader = new InputStreamReader(bis, "UTF-8");
			char[] arr = new char[100];
			while(is != null) {  // 스트림으로 반복문 제어
				// 5. 출력
				reader.read(arr);
				// ㅁㅁㅁ는 \0이고 배열의 공백을 의미한다.
				String msg = new String(arr).replace('\0', ' ');
				System.out.println("[상대] " + msg);

				// 긴 문장 후 짧은 문장이 들어올 경우 이전 값과 섞여 들어온다.
				// 초기화
				arr = new char[100];
			}
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}

}



메시지를 받을 클라이언트 Sender 클래스



package chap12.exam04.chat;

import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class Sender extends Thread {
	private Socket socket = null;
	
	public Sender(Socket socket) {
		this.socket = socket;
	}

	@Override
	public void run() {
		try {
			// 입력값을 받는 Scanner
			Scanner scan = new Scanner(System.in);
			// OutputStream으로 보내온 메시지를 전송한다.
			OutputStream os = socket.getOutputStream();
			BufferedOutputStream bos = new BufferedOutputStream(os);
			OutputStreamWriter writer = new OutputStreamWriter(bos, "UTF-8");

			while(os != null) {
				String msg = scan.nextLine();
				writer.write(msg);
				writer.flush();
				
			}
			
			scan.close();
		} catch (Exception e) {
			System.out.println(e.toString());
		}
	}

}





Receiver와 Sender을 Thread로 만들어 실행해준다.




Server


package chap12.exam04.chat;

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

public class ChatServer {

	public static void main(String[] args) {

		try {
			// 1. 소켓 생성(bind 생략 가능)
			ServerSocket server = new ServerSocket(5001);
			// 2. 접속 수락
			Socket socket = server.accept();
			System.out.println("접속 수락");
			// 3. 받기 전용 스레드 실행
			Receiver receiver = new Receiver(socket);
			receiver.start();
			// 4. 전송 전용 스레드 실행
			Sender sender = new Sender(socket);
			sender.start();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}





Client


package chap12.exam04.chat;

import java.net.Socket;

public class ChatClient {

	public static void main(String[] args) {
		try {
			// 1. 소켓 생성
			Socket socket = new Socket("여기에 IP를 입력해야 정상적으로 동작해요", 5001);
// 2. 연결 요청 // 3. 받기 전용 스레드 실행 Receiver receiver = new Receiver(socket); receiver.start(); // 4. 전송 전용 스레드 실행 Sender sender = new Sender(socket); sender.start(); } catch (Exception e) { System.out.println(e.toString()); } } }


10번째 줄에 접속할 대상의 IP를 입력해주어야 하고 1개의 컴퓨터로 테스트 할 경우


대상 Server가 자기 자신이므로 자신의 IP를 입력하면 된다.


그리고 서버는 이클립스에서 실행하고


클라이언트를 따로 실행해야 하는데


https://qdgbjsdnb.tistory.com/79 를 참조하여 cmd에서 클라이언트를 작동해보자.

+ Recent posts