Java는 클라이언트 측 프로그래밍과 서버 측 프로그래밍에 각각 사용되는 TCP 프로토콜에 대한 두 가지 클래스를 제공합니다. 애플리케이션이 통신을 시작하기 전에 먼저 클라이언트 프로그램에 의해 시작된 연결이 생성되어야 하며, 서버 측 프로그램은 항상 클라이언트의 연결을 기다리면서 호스트의 특정 포트 번호를 수신해야 합니다. 클라이언트에서는 Socket 인스턴스만 사용해야 하는 반면, 서버는 ServerSocket 인스턴스와 Socket 인스턴스를 모두 처리해야 하며 둘 다 OutputStream과 InpuStream을 사용하여 데이터를 보내고 받습니다.
지식을 학습하는 가장 좋은 방법은 이를 사용하는 것입니다. 이전 노트를 통해 우리는 이미 호스트의 주소 정보를 얻는 방법을 알고 있습니다. 이제 전송에서 TCP 프로토콜을 사용하여 소켓 프로그래밍을 처음으로 학습합니다. 층.
TCP 서버 측
소켓 프로그래밍에서 서버 측은 클라이언트 측보다 훨씬 더 복잡합니다. 서버의 역할은 통신 단말기를 구축하고 클라이언트의 연결을 수동적으로 기다리는 것입니다. 다음 서버 측 프로그램 예는 콘솔 입력에서 얻은 포트 번호를 수신하고 클라이언트가 보낸 메시지를 다시 보내는 데 사용됩니다.
다음과 같이 코드 코드를 복사합니다.
importjava.net.*;
importjava.text.MessageFormat;
importjava.io.*;
publicclassTCPEchoServer{
privatestaticfinalintBUFSIZE=32;
publicstaticvoidmain(String[]args)throwsIOException{
//TODO자동 생성된 메서드 스텁
//모니터링할 포트 번호를 콘솔에서 가져옵니다.
if(args.length!=1)
thrownewIllegalArgumentException("매개변수:<포트>");
//포트번호 알아내기
intservPort=Integer.parseInt(args[0]);
//ServerSocket 객체 인스턴스를 인스턴스화합니다.
ServerSocketservSocket=newServerSocket(servPort);
System.out.println(MessageFormat.format("수신 시작, 포트 번호: {0}",args[0]));
//초기 수신 데이터의 총 바이트 수
intrecvMsgSize;
//데이터 수신을 위한 버퍼
바이트[]receiveBuf=newbyte[BUFSIZE];
//반복을 반복하고, 포트 번호를 수신하고, 새로운 연결 요청을 처리합니다.
동안(참){
//차단 후 대기, 요청이 수신될 때마다 새 연결 인스턴스 생성
SocketclntSocket=servSocket.accept();
//연결된 클라이언트의 SocketAddress를 가져옵니다.
SocketAddressclientAddress=clntSocket.getRemoteSocketAddress();
//연결 클라이언트 주소 정보를 출력한다.
System.out.println("Handlingclientat"+clientAddress);
//클라이언트로부터 데이터를 받는 객체
InputStreamin=clntSocket.getInputStream();
//클라이언트에게 데이터를 보내는 객체
OutputStreamout=clntSocket.getOutputStream();
//클라이언트가 보낸 데이터를 읽어서 클라이언트로 보낸다.
while((recvMsgSize=in.read(receiveBuf))!=-1){
out.write(receiveBuf,0,recvMsgSize);
}
//클라이언트가 연결을 닫으면 연결을 닫습니다.
System.out.println("클라이언트가 연결을 종료합니다.");
clntSocket.close();
}
}
}
TCP 클라이언트
소켓 프로그래밍에서는 먼저 클라이언트가 서버에 메시지를 보낸 다음 수동적으로 서버의 응답을 기다려야 합니다. 다음 예에서는 서버에 정보를 보내고 서버가 보낸 메시지를 기다린 후 인쇄합니다.
다음과 같이 코드 코드를 복사합니다.
importjava.io.*;
importjava.net.Socket;
importjava.net.SocketException;
publicclassTCPEchoClient{
publicstaticvoidmain(String[]args)throwsIOException{
//TODO자동 생성된 메서드 스텁
//콘솔로부터 수신된 매개변수가 올바른지 확인
if((args.length<2)||(args.length>3))
thrownewIllegalArgumentException(
"매개변수:<서버><워드>[<포트>]]");
//서버 주소 가져오기
문자열서버=args[0];
//전송해야 할 정보를 가져옵니다.
바이트[]data=args[1].getBytes();
//슬레이브 매개변수가 3개인 경우 정보 전송을 위한 포트 번호를 가져옵니다. 기본 포트 번호는 8099입니다.
intservPort=(args.length==3)?Integer.parseInt(args[2]):8099;
//서버 주소와 포트 번호를 기반으로 소켓 인스턴스를 인스턴스화합니다.
Socketsocket=newSocket(서버,servPort);
System.out.println("서버에 연결되었습니다...sendingechostring");
//서버로부터 받은 데이터 객체인 이 소켓의 입력 스트림을 반환합니다.
InputStreamin=socket.getInputStream();
//서버로 전송된 데이터 객체인 이 소켓의 출력 스트림을 반환합니다.
OutputStreamout=socket.getOutputStream();
//콘솔에서 받은 데이터를 서버로 보냅니다.
out.write(데이터);
//데이터를 수신하는 카운터는 데이터의 초기 오프셋을 씁니다.
inttotalBytesRcvd=0;
//수신된 데이터의 전체 바이트 수를 초기화합니다.
intbytesRcvd;
while(totalBytesRcvd<data.length){
//서버가 연결을 닫으면 -1을 반환합니다. read 메서드는 수신된 데이터의 총 바이트 수를 반환합니다.
if((bytesRcvd=in.read(data,totalBytesRcvd,data.length)
-totalBytesRcvd))==-1)
thrownewSocketException("서버 연결이 종료되었습니다.");
totalBytesRcvd+=bytesRcvd;
}
//서버가 보낸 데이터를 출력한다.
System.out.println("수신됨:"+newString(data));
//연결을 닫습니다.
소켓.닫기();
}
}
먼저 서버를 실행하고 포트 8099에서 수신 대기합니다.
그런 다음 클라이언트 프로그램을 실행하고 서버에 메시지를 보냅니다.
서버 측 콘솔을 다시 보면 이전 클라이언트 연결의 주소 정보를 볼 수 있습니다.