Backend/JAVA

JAVA 소켓프로그래밍 Network TCP

쏠솔랄라 2023. 3. 13. 16:55

 

 

소켓프로그래밍 Network TCP

 

소켓프로그래밍 : 채팅

 

통신방식
     UDP : 비연결형 ; 무전기, 개인 쪽지, 문자메세지
     TCP : 연결형 ; 핸드폰, 1:1채팅
        * TCP : Socket, ServerSocket
        상대방과 1:1로 연결이 유지되는 객체

 

 

// Server(Receiver) class
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer {
public static void main (String[] args) {

// 서버소켓 열기
ServerSocket server = null;

try {
server = new ServerSocket(56789);
System.out.println(server.getLocalPort());
//System.out.println(server.getLocalSocketAddress());
} catch (IOException e) {
e.printStackTrace();
}

Socket socket = null;

try {
socket = server.accept(); 
// 연결 될 때까지 상대방의 정보를 저장한 socket을 반환한다

System.out.println(socket.getRemoteSocketAddress()); // 클라이언트한테 들어온 정보
System.out.println(socket.getLocalAddress()); // 서버의 정보
} catch (IOException e) {
e.printStackTrace();
}

InputStream is = null;
OutputStream os = null;

try {
is = socket.getInputStream();
os = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}

/*
DataIn, Out | ObjectIn, Out | BufferedReader, BufferedWriter | PrintWriter, Scanner
로 변형시켜 데이터를 주고받을 수 있다
*/


DataInputStream dis = null;
DataOutputStream dos = null;

dis = new DataInputStream(is);
dos = new DataOutputStream(os);

try {
String request = dis.readUTF();
System.out.println(request);

dos.writeUTF("문자열 전송!");
} catch (IOException e) {
e.printStackTrace();
}

try {
if (dos !=null) {
dos.close();
}
if (dis !=null) {
dis.close();
}
if (socket !=null) {
socket.close();
}
if (server !=null) {
server.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

 

 

출력화면

(포트값 출력)

 

 

// Client(Sender) class


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {

public static void main (String[] args) {

Socket socket = null;

try {
socket = new Socket ("192.168.0.45", 56789);
// 객체 생성에 성공하게 되면 상대방과 연결되었다는 듯
System.out.println(socket.getLocalPort());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

// InputStream, OutputStream 을 통해서 데이터를 주고 받는다.
InputStream is = null;
OutputStream os = null;

try {
is = socket.getInputStream();
os = socket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}

/*
DataIn, Out | ObjectIn, Out | BufferedReader, BufferedWriter | PrintWriter, Scanner
로 변형시켜 데이터를 주고받을 수 있다
*/

DataInputStream dis = null;
DataOutputStream dos = null;

dis = new DataInputStream(is);
dos = new DataOutputStream(os);

try {
dos.writeUTF("장모씨"); // UTF-8 형식으로 문자열을 변환
// dos.writeBytes("장모씨"); // 바이트로 변환해서 보내는 것

String request = dis.readUTF();
System.out.println(request);
} catch (IOException e) {
e.printStackTrace();
}
}
}

 

 

출력화면

Display selceted console 창에서 client 출력

 

 


 

 

CMD에서 통신 확인하기

c:

cd [bin 폴더경로]

sender.TCPClient

 

c:

cd [bin 폴더경로]

receiver.TCPServer

 

 


 

 

Exercise 1

 

1:1 채팅 -> 다중채팅 -> Socket관리

TCP 방식으로
클라이언트 - ChatClient

서버 - ChatServer
Thread가 두 개
input - Receiver
output - Sender

 

총 4개의 클래스를 생성해 출력

 

// class ChatClient

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

public class ChatClient {

/*
1:1 채팅 -> 다중채팅 -> Socket관리
TCP 방식으로
클라이언트 - ChatClient
서버 - ChatServer

Thread가 두 개
input - Receiver
output - Sender
*/

public static void main (String[] args) {

try(Socket so = new Socket("192.168.12.81", 33333)){

new Thread(new Sender(so)).start();
new Receiver(so).run();

} catch (IOException e) {
e.printStackTrace();
}
}
}

 

 

// class ChatServer

import java.net.ServerSocket;

import java.io.IOException;

import java.net.Socket;

public class ChatServer {

/*

1:1 채팅 -> 다중채팅 -> Socket관리

TCP 방식으로

클라이언트 - ChatClient

서버 - ChatServer

Thread가 두 개

input - Receiver

output - Sender

*/

 

public static void main(String[] args) {

try(ServerSocket ss = new ServerSocket(33333)) {

try (Socket so = ss.accept()) {

new Thread(new Sender(so)).start();

new Receiver(so).run();

} catch (IOException e) {

e.printStackTrace();

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

 

// class Receiver

package chat;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.NoSuchElementException;
import java.util.Scanner;

public class Receiver implements Runnable {

private Scanner sc;
private PrintWriter pw;
private Socket so;
private String msg;

public Receiver (Socket so) {
this.so = so;

try {
sc = new Scanner(so.getInputStream());
pw = new PrintWriter(System.out);
} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void run() {

try {

while (true) {
msg = sc.nextLine();
pw.println(msg);
pw.flush(); // 출력버퍼를 비움

if("exit".equals(msg)) {
break;
} else if (so.isClosed()) {
break;
}
}
} catch (NoSuchElementException e) {
System.err.println("대화가 종료되었습니다.");
}

sc.close();
pw.close();

try {
so.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("receiver : " + so.isClosed());
}
}

 

 

// class Sender

package chat;

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

public class Sender extends Thread {

private Scanner sc;
private PrintWriter pw;
private Socket so;
private String msg;

public Sender (Socket so) {
this.so = so;

try {
sc = new Scanner(System.in);
pw = new PrintWriter(so.getOutputStream());

} catch (IOException e) {
e.printStackTrace();
}
}

@Override
public void run () {
while(true) {
msg = sc.nextLine();

pw.println(msg);
pw.flush();

if("exit".equals(msg)) {
break;
} else if(so.isClosed()) {
break;
}
}

sc.close();
pw.close();

try {
so.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("sender : " + so.isClosed());
}
}