기본 웹의 구조는 클라이언트가 먼저 말을 걸 수 밖에 없음
근데 채팅은 양쪽이 얘기해야한다는 특수성이 있음
- 채팅 만들기
채팅은 통신이기 때문에 꼭 소켓부터 만들어줘야함, Thread도 상속받아야
ChatClient 얘로 서버에 접속해줌, 여기서 사용한 sender와 receiver는 따로 만들어
public class ChatClient {
public static void main(String[] args) throws Exception{
//1.소켓 생성
Socket socket = new Socket("192.168.12.77",5252);
//2. 예외가없다면 접속성공
System.out.println("접속성공");
//3. 요청할거 하고
Sender sender = new Sender(socket);//sender thread만들고
Receiver receiver = new Receiver(socket);
sender.start();
receiver.start();
//4. 접속종료
System.out.println("접속종료");
}
}
얘는 서버, 설명읽어보면 다 알 수 있음..
public class ChatServer {
public static void main(String[] args) throws Exception{
//1.서버소켓생성
ServerSocket server = new ServerSocket(5252);
//2. 클라이언트 확인
Socket socket = server.accept();
System.out.println("접속수락");
//3. 할일한다(상대방에대한 정보니까 stream활용해서
Sender sender = new Sender(socket);//sender thread만들
Receiver receiver = new Receiver(socket);
sender.start();
receiver.start();
}
}
Receiver 클래스, 얘를 통해 받아줌(input), 그리고 한번만 받을거아니고 계속 받아야하니까 while넣어줘 입력하는 코드만 그 사이에 넣어주면돼
//상대한테 받기만하는 스레드->통신할거라서 소켓 무조건 필요
public class Receiver extends Thread{
private Socket socket; //상대방에대한 정보를 다 가지고 있는거고
private ObjectInputStream ois; //정보를 보낼 수 있는 통로
//이기때문에 private으로 막아놓은 것임
public Receiver(Socket socket) {//다른데서도 쓸거라서 sender는 익명객체로 안만듦
this.socket = socket;
}
@Override
public void run() {
try {
ois = new ObjectInputStream(socket.getInputStream());
while (true) {
String msg = ois.readUTF();
System.out.println("상대 > "+msg);
}
} catch (IOException e) {
e.printStackTrace();
//예외발생시 ois와socket닫기(생략 닫을 때 trycatch한번 더 들어가니까 복잡해져서 걍 뺌)
}
}
}
Sender클래스, 얘도 설명 읽으면 다 알 수 있삼..
public class Sender extends Thread{
private Socket socket = null; // 클래스 전체에서 쓰기위해 따로 빼놓음
private ObjectOutputStream oos = null; //=null을 쓰나 안쓰나 차이없음, 그냥 아무것도 없다고 보여주는거
public Sender(Socket socket) {//다른데서도 쓸거라서 sender는 익명객체로 안만듦
this.socket = socket;
}
@Override
public void run() {
try {
//콘솔로 입력을 받고
Scanner scan = new Scanner(System.in);//자바시스템안에서 쓰는 인풋
//소켓으로부터 아웊스트림, 보조스트림
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
while(true) {//전송하고 내보내는 것만 while반복하도록
String msg = scan.nextLine();
//문자열 받기 위해 nextline,얘도 스캔으로부터 입력받은게 또 있기 전까지는 밑에 문을 실행하지 않음 -> blocking 역할도 함
System.out.println("당신 > "+msg);
oos.writeUTF(msg);//전송
oos.flush();
//내보내기 및 종료
}
} catch (IOException e) {//예외처리도 while문 밖에
e.printStackTrace();
//예외발생시 소켓종료(생략)
}
}
}
- 채팅에선 문자열만 주고받았다면 이번엔 파일도 주고받기
"C:\\img\\img01.jfif" 이 파일을 "C:/Users/GDJ63/Downloads/"+fileName 여기로 보낼 것임
전송할 파일을 읽어오고 그 파일을 Receiver에서 받게끔 다시 보내주기
public class FileSender {
public static void main(String[] args) throws Exception{
//client role
//1.소켓
Socket socket = new Socket("192.168.12.83",7777);
System.out.println("접속 성공");
//2.접속성공(내 저장소에 있는 파일을 읽어올거임)
//2-1. 주스틂과 보조슮 사용
File file = new File("C:\\img\\img01.jfif");
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
long size = file.length();
String fileName = file.getName();
System.out.println("size : "+size);
/*
byte[]arr = new byte[(int) size];
bis.read(arr);
*/
//2-2. 스릍ㄻ으로 데이터 읽어옴
//2-3. 소켓에서 stream 추출
//3.소켓에서 스트림 추출(OutputStream) 보조스트림
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
//주스트림이 버퍼에탑승한 후 자바 고유 데이터 타입으로 추출하기 위해 data도 탑승함
//4.전송
dos.writeUTF(fileName);
dos.writeLong(size);
//dos.write(arr);
int data= 0;
while((data = bis.read()) != -1) {
dos.write(data);
}
//5. 내보내기+자원 정리
dos.flush();
System.out.println("전송완료");
dos.close();
bis.close();
socket.close();
}
}
while((data = bis.read()) != -1) {
dos.write(data);
}
이 부분은
값을 불러온 bis를 read()통해 읽고 그걸 data에 담았는데 (앞에서 변수 선언해줘야함) 그게 만약 -1이 아니라면
data값을 dos에 써라
이 뜻임
-1이 나오면 완료되었다는 뜻이니까
이제 Receiver에서 받고 그 사진을 다시 폴더로 전송할거임
그니까 총 순서는 '폴더1 안 파일1 ->Sender -> Receiver - > 폴더2 안에 파일1 입력
public class FileReceiver {
public static void main(String[] args) throws Exception{
//server role
//1. 서버소켓
ServerSocket server = new ServerSocket(7777);
while(true) {//2. 요청 대기및 수락
System.out.println("요청대기");
Socket socket = server.accept();
System.out.println("요청 수락");
//요청이 들어오는것만다 자기가할건지, 스레드를 하나씩 던져줄건지 정해야함
//여러 요청을 빠르게 처리하기 위해 스레드를 사용할거임
Thread th = new Thread() {
@Override
public void run() {
//3. 소켓으로부터 스트림추출(InputStream) + 보조스트림(
try {
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
DataInputStream dis = new DataInputStream(bis);
//4. 읽어온내용은 자체 저장소에 저장시켜야함
String fileName = dis.readUTF();
long size = dis.readLong();
System.out.println("size : "+size);
//byte[]arr = dis.readAllBytes();
int data=0;
//4-1. outputstream -> fileoutputstream.write()
FileOutputStream fos = new FileOutputStream("C:/Users/GDJ63/Downloads/"+fileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
//5. 읽어온 내용 내보내기
//bos.write(arr);
while((data = dis.read())!= -1) {
bos.write(data);
}
//6. 자원정리
bos.flush();
dis.close();
bos.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
};
th.start();
}
}
}
요청은 하나만 들어오는게 아니니까 스레드를 만들어서 처리해줬음!
maria db 다운받는 과정
잃어버리면안되는 비번설정
dbeaver 다운받는 과정
sql 열때마다 이걸로 열게~ 하는
db기억해야될거 적음
insert로 집어넣으면
와일드카드=범위신경쓰지 않고 쓰겠다
'Spring' 카테고리의 다른 글
국비코딩 [Maria DB] 제약조건, 서브쿼리 (0) | 2023.03.21 |
---|---|
국비코딩 Mar20 | db 기초 정리, 테이블 생성, 수정, dml (0) | 2023.03.20 |
국비코딩 Mar16 | 블로킹, IP, TCP (0) | 2023.03.16 |
국비코딩 Mar15 | round robin, synchronized,Thread Pool, Demon Thread (0) | 2023.03.15 |
국비코딩 Mar14 | JAVA NIO, Thread, Multi Thread, 익명객체 (0) | 2023.03.14 |