TCP 네트워킹
2022. 5. 7. 15:23ㆍjava/java
TCP(Transmission Control Protocol)
1)특징
- 연결 지향적 프로토콜 -> 시간 소요가 됨
- 통신 선로 고정 -> 전송 속도 느려질 수도 있음
- 데이터를 정확하고 안정적으로 전달
2)java.net API
- ServerSocket, Socket
3)ServerSocket과 Socket 용도
ServerSocket 생성과 연결 수락
1) ServerSocket 생성과 포트 바인딩
ServerSocket serverSocket = new ServerSocket(5001); //해당 포트에 바인딩된 서버 소켓 객체 얻기
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("127.0.0.1", 5001);//객체 생성후 바인드 메소드를 이용해서
//로컬 호스트의 아이피 주소와 바인딩할 포트
//번호
2) 연결 수락
- accept() -> 클라이언트가 연결요청을 하기 전 까지 대기상태/ 연결 요청을 받으면 통신용 소켓을 리턴
try {
Socket socket = serverSocket.accept(); //서버 소켓을 생성하고 accept()메소드를 사용
} catch(Exception e){}
- 연결된 클라이언트 IP 주소 얻기
InetSocketAddress socketAddress = (InetSocketAddress) socket.getRemoteSocketAddress();
socketAddress.getHostName() -> 클라이언트 IP 리턴
socketAddress.getPort() -> 클라이언트 포트 번호 리턴
socketAddress.toString() -> "IP:포트번호" 형태의 문자열 리턴
3) ServerSocket 포트 언바인딩
-serverSocket.close();
*Socket 생성과 연결 요청
1) Socket 생성 및 연결 요청
try {
Socket socket = new Socket("localhost", 5001); //방법1
Socket socket = new Socekt( new InetSocketAddress("localhost", 5001); //방법2
} catch (UnknownHostException e) {
//IP 표기 방법이 잘못되었을 경우
} catch (IOException e) {
//해당 포트의 서버에 연결할 수 없는 경우
}
socket = new Socket();
socket.connect( new InetSocketAddress("localhost", 5001) );
2) 연결 끊기
try {
socket.close();
} catch (IOException e) {}
Socket 데이터 통신
1) 입출력 스트림 얻기
//입력 스트림 얻기
InputStream is = socket.getInputStream();
//출력 스트림 얻기
OutputStream os = socket.getOutputStream();
2) 데이터 보내기
String data = "보낼 데이터";
byte[] byteArr = data.getBytes("UTF-8");
OutputStream outputStream = socket.getOutputStream();
ouputStream.write(byteArr);
outputStream.flush();
3) 데이터 받기
byte[] byteArr = new byte[100];
InputStream inputStream = socket.getInputStream();
int readByteCount = inputStream.read(byteArr);
String data = new String(byteArr, 0, readByteCount, "UTF-8");
4) read()의 블로킹 해제
블로킹이 해제되는 경우 | 리턴값 |
상대방이 데이터를 보냄 | 읽은 바이트 수 |
상대방이 정상적으로 Socket의 close()를 호출 | -1 |
상대방이 비정상적으로 종료 | IOException 발생 |
package sec07.exam02_data_read_write;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class SeverExample {
public static void main(String[] args) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket();
serverSocket.bind(new InetSocketAddress("localhost", 5001));
while(true) {
System.out.println("[연결 기다림]");
Socket socket = serverSocket.accept();
InetSocketAddress isa = (InetSocketAddress) socket.getRemoteSocketAddress();
System.out.println("[연결 수락함]" + isa.getHostName());
byte[] bytes = null;
String message = null;
InputStream is = socket.getInputStream();
bytes = new byte[100];
int readByteCount = is.read(bytes);
System.out.println(readByteCount);
message = new String(bytes, 0, readByteCount,"UTF-8");
System.out.println("[데이터 받기 성공]:" + message);
OutputStream os = socket.getOutputStream();
message = "Hello Client";
bytes = message.getBytes("UTF-8");
os.write(bytes);
os.flush();
System.out.println("[데이터 보내기 성공]");
is.close();
os.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
if(!serverSocket.isClosed()) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
-------------------------------------------------------------------------------
package sec07.exam02_data_read_write;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
public class ClieantExample {
public static void main(String[] args) {
Socket socket = null;
try {
socket = new Socket();
System.out.println("[연결 요청]");
socket.connect(new InetSocketAddress("localhost", 5001));
System.out.println("[연결 성공]");
byte[] bytes = null;
String message = null;
OutputStream os = socket.getOutputStream();
message = "Hello Server";
bytes = message.getBytes("UTF-8");
os.write(bytes);
os.flush();
System.out.println("[데이터 보내기 성공]");
InputStream is = socket.getInputStream();
bytes = new byte[100];
int readByteCount = is.read(bytes);
message = new String(bytes, 0, readByteCount, "UTF-8");
System.out.println("[데이터 받기 성공]:" + message);
os.close();
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {}
}
}
}