소켓(Socket)은 TCP/IP 기반 네트워크 통신에서 데이터 송수신의 접점을 의미, 서버 - 클라이언트 간 데이터를 주고받는 양방향 연결 지향성 통신 , 소켓 통신은 지속적으로 연결을 유지하면서 실시간으로 데이터를 주고받아야 하는 경우에 사용
소켓은 클라이언트 소켓과 서버 소켓으로 구분되며, 소켓간 통신을 위해서는 네트워크상에서 클라이언트와 서버에 해당되는 컴퓨터를 식별하기 위한 IP주소와 해당 컴퓨터내에서 현재 통신에 사용되는 응용프로그램을 식별하기 위한 포트번호가 사용
http 프로토콜
A : server 야 이거 B 한테 줘
B : server 야 뭐 온거 없어?
server : A 가 너 주래
ServerSocket serverSocket = new ServerSocket(@@@@) //@@@@ : 포트번호
Socket socket = serverSocket.accept();
InputStream ins = socket.getInputStream();
OutputStream outs = socket.getOutputStream();
byte[] inputData = new byte[100];
int length = ins.read(inputData);
String inputMessage = new String(inputData,0,length);
String outputMessage = "전송할 메시지 입력: ";
outs.write(outputMessage.getBytes());
out.flush();
socket.close();
serverSocket.close();
Socket socket = new Socket("127.0.0.1",@@@@) // IP주소 및 포트번호
InputStream inC = socket.getInputStream();
OutputStream outC = socket.getOutputStream();
String outputMessage = "전송할 메시지 입력: ";
outs.write(outputMessage.getBytes());
out.flush();
byte[] inputData = new byte[100];
int length = ins.read(inputData);
String inputMessage = new String(inputData,0,length);
socket.close();
데이터 전송의 기본단위는 바이트(Byte)로 문자의 경우 데이터 전송시 문자를 바이트로, 수신시 바이트로 문자로 변환이 필요, 앞에서는 String Class의 생성자와 getBytes method를 사용
JAVA에는 이 변환을 편리하게 해주는 클래스인 InputStramReader와 OutputStreamWriter가 있으며 charset을 지정하여 사용할 수 있음, 또한 효율적인 데이터 입출력을 위해 바로 전달하지 않고 중간에 버퍼를 사용하는데 이때 사용하는 클래스가 BufferedReader 와 BufferedWriter
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
PrintWriter, PrintStream 클래스가 있음PrintWriter pw = new PrintWrier(socket.getOutputStream());
PrintStream ps = new PrintStream(socket.getOutputStream());
Server
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class SocketServer {
public static final int PORT = 9090;
public static void main(String[] args) {
List<Socket> clients = new ArrayList<>();
try {
ServerSocket serverSocket = new ServerSocket(PORT);
while(true) {
System.out.println("클라이언트의 접속을 기다리는 중입니다.");
Socket socket = serverSocket.accept();
clients.add(socket);
System.out.println("클라이언트가 연결되었습니다.");
System.out.println(clients);
OutputStream outputStream = socket.getOutputStream();
PrintWriter out = new PrintWriter(outputStream, true);
out.println("___서버에 접속한 것을 환영합니다.");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 9090);
System.out.println("서버에 접속 성공!");
InputStream inputStream = socket.getInputStream();
InputStreamReader streamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(streamReader);
System.out.println(reader.readLine());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Server
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
private static final int PORT = 9090;
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("서버를 실행합니다.");
while(true) {
Socket socket = serverSocket.accept();
SocketServer socketServer = new SocketServer(socket);
socketServer.start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("서버를 종료합니다.");
}
}
}
SocketServer
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class SocketServer extends Thread {
public static List<SocketServer> clientList = new ArrayList<>();
private Socket socket;
private String name;
public SocketServer(Socket socket) {
this.socket = socket;
clientList.add(this);
}
@Override
public void run() {
System.out.println("[연결된 클라이언트 정보]");
System.out.println("IP: " + socket.getInetAddress());
try {
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
OutputStream outputStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(outputStream, true);
writer.println("서버 접속 성공!");
writer.println("사용자 이름을 입력하세요!");
String message = null;
boolean loginFlag = false;
while((message = reader.readLine()) != null) {
if(name == null) {
name = message;
System.out.println("\n서버에 " + name + "님이 접속하였습니다.");
}
for(SocketServer s : clientList) {
try {
outputStream = s.socket.getOutputStream();
writer = new PrintWriter(outputStream, true);
if(!loginFlag) {
writer.println("\n" + s.name + "님이 접속하였습니다.");
loginFlag = true;
continue;
}
writer.println("\n" + s.name + ": " + messase);
} catch (IOException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static String name;
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 9090);
System.out.println("서버에 접속함?");
ClientRecive clientRecive = new ClientRecive(socket);
clientRecive.start();
ClientSend clientSend = new ClientSend(socket);
clientSend.start();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientRecive
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class ClientRecive extends Thread {
private final Socket socket;
@Override
public void run() {
try {
InputStream inputStream = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
while(true) {
System.out.println(reader.readLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ClientSend
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
import com.mysql.cj.jdbc.exceptions.MySQLStatementCancelledException;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class ClientSend extends Thread {
private final Socket socket;
@Override
public void run() {
try {
OutputStream outputStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(outputStream, true);
Scanner scanner = new Scanner(System.in);
while(true) {
if(Client.name == null) {
Client.name = scanner.nextLine();
writer.println(Client.name);
continue;
}
writer.println(scanner.nextLine());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class LoopThread extends Thread {
private String threadName;
public LoopThread(String threadName) {
this.threadName = threadName;
}
@Override
public void run() {
for (int i = 0; i< 10; i++) {
System.out.println(threadName + ":" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
LoopThread loopThread1 = new LoopThread("김상현");
LoopThread loopThread2 = new LoopThread("강대협");
LoopThread loopThread3 = new LoopThread("손지호");
LoopThread loopThread4 = new LoopThread("김재영");
loopThread1.setPriority(6);
loopThread4.setPriority(7);
System.out.println(loopThread1.getPriority());
System.out.println(loopThread2.getPriority());
System.out.println(loopThread3.getPriority());
System.out.println(loopThread4.getPriority());
loopThread1.start(); // start가 호출되면 LoopThread.run()이 실행된다.
loopThread2.start();
loopThread3.start();
loopThread4.start();
/*
* Thread
* 숫자가 클 수록 우선순위가 높음
*
*/
}
}