bdfgdfg

자바 소켓프로그래밍 본문

웹프로그래밍/Java

자바 소켓프로그래밍

marmelo12 2023. 8. 1. 15:50
반응형

IP주소(IP Address)

IP주소는 컴퓨터를 구분하는데 사용되는 고유한 값이다.

IP주소는 4Byte(IPv4)의 정수로 구성되어 있고, 4개의 정수가 마침표를 구분자로 구성된다.(즉 마침표마다 0~255의 값을 가짐)

IP주소는 네트워크 주소와 호스트주소로 나눌 수 있는데 각각 몇bit를 차지하는지는 네트워크를 어떻게 구성하는지에 따라 달라진다.

 

URL(Uniform Resource Locator)

URL은 인터넷에 존재하는 여러 서버들이 제공하는 자원에 접근할 수 있는 주소를 표현하기 위한 것.

 - '프로토콜://호스트명:포트번호/경로명/파일명?쿼리스트링#참조'

 - URL에서 포트번호,쿼리,참조는 생략할 수 있다.

http://www.codechobo.com:80/sample/hello.html?referer=codechobo#index1

프로토콜 : 자원에 접근하기 위해 서버와 통신하는데 사용하는 통신규약(http)

호스트명 : 자원을 제공하는 서버의 이름(www.codechobo.com)

포트번호 : 통신에 사용되는 서버의 포트번호(80)

경로명 : 접근하려는 자원이 저장된 서버상의 위치(/sample/)

파일명 : 접근하려는 자원의 이름(hello.html)

쿼리: URL에서 ?이후의 부분(referer=codechobo)

참조 : URL에서 # 이후의 부분(index1)

포트 번호 생략시 http프로토콜에서 사용하는 80번 포트라고 간주

 

자바에서는 위와같이 URL을 다루기위한 클래스를 제공한다.

 

소켓프로그래밍

소켓은 네트워크 통신을 위한 파일 디스크립터,핸들이다.

 

TCP와 UDP

TCP/UDP는 전송계층에 해당하는 프로토콜로 TCP와 UDP는 전송방식이 다르며 각 방식에 따른 장단점이 있다.

 -> 거의 대부분의 통신은 TCP를 사용.

https://shjz.tistory.com/98

TCP는 연결할 때 3Way-handshake, 종료할 떄 4way-handshake등의 과정을 거치며, 데이터를 송수신할때마다 데이터가 순서대로 왔는지. 제대로 도착했는지를 확인하는 절차를 매번 거친다.

 -> UDP는 위와 같은 절차가없음. 그렇기에 TCP가 UDP에 비해 상대적으로 속도가 느린편.

 -> 또한 TCP는 실제로 연결(물리적인 연결)이 되는게 아닌, 논리적인 연결이다.

 

TCP서버의 통신과정은 다음과 같음.

1. 서버 프로세스는 서버소켓을 이용해 서버 컴퓨터의 특정 포트에서 클라이언트의 연결요청을 처리할 준비를 한다.

2. 클라이언트 프로세스는 접속할 서버의 IP와 포트정보를 들고, 소켓을 생성해 서버에 연결을 요청.

3. 서버소켓은 클라이언트의 연결요청을 받으면 서버에 새로운 소켓을 생성해, 클라이언트의 소켓과 연결되도록 한다.

 -> 해당 소켓은 클라이언트와 연결된 소켓.

4. 서버소켓은 C 소켓 통신때 배운 리슨소켓의 역할을 하는 것.

 

소켓은 두 개의 스트림, 입출력 스트림을 들고있으며 이 스트림들은 연결된 상대편 소켓의 스트림들과 교차연결된다.

 

자바에서는 TCP를 이용한 소켓프로그래밍을 위해 Socket과 ServerSocket 클래스를 제공한다.

Socket : 프로세스간의 통신을 담당. InputStream과 OutputStream을 가짐

ServerSocket : 주소 및 포트와 바인딩 되어 외부의 연결요청을 기다리다 연결요청이 들어오면 Socket을 생성해 소켓과 소켓과의 통신이 이루어지도록 한다. 

 -> InetAddress https://mainpower4309.tistory.com/22

 

Server.class

public class Hello {
	
	public static String getTime()
	{
		SimpleDateFormat f = new SimpleDateFormat("{hh:mm:ss}");
		return f.format(new Date());
	}
	
	public static void main(String[] args) throws Exception
	{
		ServerSocket serverSocket = null;
		try
		{
			serverSocket = new ServerSocket(7777);
		}
		catch(Exception e)
		{
			e.printStackTrace();  
		}
		
		while(true)
		{
			try
			{
				// 연결이 들어온 Socket을 반환한다.
				Socket socket = serverSocket.accept();
				if(socket == null)
				{
					// 로깅처리
					break;
				}
				System.out.println(getTime() + " " + socket.getInetAddress().getHostAddress() + "주소가 연결.");
				OutputStream out = socket.getOutputStream();
				DataOutputStream dos = new DataOutputStream(out);
				
				dos.writeUTF("안녕.");
				dos.close();
				socket.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				serverSocket.close();
				break;
			}
		}
		
	}
}

TCP환경의 서버 자바코드이며, 간단하게 연결된 소켓이 있다면 메세지를 보내고 바로 해당 소켓을 닫는 코드.

 

클라이언트 코드

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
		String serverIp = "127.0.0.1";
		
		Socket socket = new Socket(serverIp, 7777);
		
		InputStream in = socket.getInputStream();
		DataInputStream dis = new DataInputStream(in);
		
		System.out.println(dis.readUTF());
		}
		catch( Exception e)
		{
			e.printStackTrace();
		}
	}

}

서버가 보낸 메시지를 받는처리.

메세지를 잘 전달받은걸 알 수 있다.

 

참고로 127.0.0.1 ip는 루프백 주소라고 하며, 호스트 자기자신을 가리키는 IP를 뜻한다.

 

소켓프로그래밍은 좀 더 따로 공부하도록하고, 개인적으로 궁금한것들 해볼예정.

public class Hello {
	
	public static String getTime()
	{
		SimpleDateFormat f = new SimpleDateFormat("{hh:mm:ss}");
		return f.format(new Date());
	}
	
	public static void main(String[] args) throws Exception
	{
		ServerSocket serverSocket = null;
		try
		{
			serverSocket = new ServerSocket(7777);
		}
		catch(Exception e)
		{
			e.printStackTrace();  
		}
		
		while(true)
		{
			try
			{
				// 연결이 들어온 Socket을 반환한다.
				Socket socket = serverSocket.accept();
				if(socket == null)
				{
					// 로깅처리
					break;
				}
				System.out.println(getTime() + " " + socket.getInetAddress().getHostAddress() + "주소가 연결.");
				OutputStream out = socket.getOutputStream();
				ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
				
				System.out.println("연결된 소켓의 로컬포트 : " + socket.getLocalPort() );
				
				TestClass T = new TestClass("Hello I'm Server",100,500);
				objectOutputStream.writeObject(T);
				objectOutputStream.flush();
				
				objectOutputStream.close();
				socket.close();
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				serverSocket.close();
				break;
			}
		}
		
	}
}

따로 외부 프로젝트에 TestClass를 만들어 해당 클래스는 직렬화가능한 클래스로 만들었다.

해당 클래스를 직렬화해 서버에서 클라이언트로 데이터를 보내보면

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try {
		String serverIp = "127.0.0.1";
		
		Socket socket = new Socket(serverIp, 7777);
		
		InputStream in = socket.getInputStream();
		ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
        TestClass T = (TestClass)objectInputStream.readObject(); // readObject는 object 객체로 불러오기 때문에 형변화해야 합니다.
        
        System.out.println(T.toString());
		objectInputStream.close();
		}
		catch( Exception e)
		{
			e.printStackTrace();
		}
	}

}

name : Hello I'm Server, age : 100, privateNum : 500

잘 읽힌다.

반응형

'웹프로그래밍 > Java' 카테고리의 다른 글

Mybatis 프레임워크  (0) 2023.11.07
자바 소켓통신  (0) 2023.10.08
자바의 직렬화  (0) 2023.08.01
스트림(Stream)  (0) 2023.07.30
람다  (0) 2023.07.30
Comments