자바 socket 통신 흐름 테스트
8768 단어 java socket
클 라 이언 트 서버 연결 만 들 기
클 라 이언 트 가 서버 에 데 이 터 를 보 내 처리 합 니 다.
서버 에서 입력 흐름 에서 데이터, 처리 중.....
이 때 클 라 이언 트 가 연결 을 끊 습 니 다.
서버 에서 처 리 된 데 이 터 를 고객 에 게 보 냅 니 다. 예상 되 는 경우 연결 이 끊 겼 고 출력 흐름 이 존재 하지 않 습 니 다. write 할 때 오 류 를 보고 해 야 합 니 다.
package tcp;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
public class TcpClient {
public static void main(String[] args) {
try {
Socket s = new Socket("127.0.0.1", 8080);
// s.setTcpNoDelay(true);
// InputStream is = s.getInputStream();
OutputStream os = s.getOutputStream();
DataOutputStream os_d = new DataOutputStream(os);
for (;;) {//
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader read = new BufferedReader(input);
String content = read.readLine();
if ("exit".equals(content)) {
s.close();
return;
}
System.out.println(" ," + content);
os_d.writeBytes(content + System.getProperty("line.separator"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package tcp;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
//
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("tcp ....");
while (1 == 1) {
Socket socket = serverSocket.accept();//
socket.setOOBInline(false);
System.out.println(" " + socket);
// socket.setSoTimeout(10*1000);//readLine 10s, java.net.SocketTimeoutException
// socket
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
System.out.println(" ...");
while (true) {//
System.out.println(" ");
String readLine = bufferedReader.readLine();
if (readLine == null) {
return;
}
System.out.println(" :" + readLine);
try {
System.out.println(" .....");
Thread.sleep(10*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
StringBuffer sb=new StringBuffer();
// for(int i=0;i<10000;i++)
// sb.append("aaaaaaaaaaaaaa");
bufferedWriter.write(readLine+","+sb.toString());
bufferedWriter.flush();
System.out.println(" OK");
try {
Thread.sleep(10*1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
클 라 이언 트 콘 솔
aaa
메시지 보 내기 시작
exit
서버 콘 솔
tcp 서버 오픈...
소켓 [addr =/127.0.1, port = 3643, localport = 8080] 연결 을 가 져 왔 습 니 다.
클 라 이언 트 정보 수신...
사용자 입력 대기
메시지 수신: aaa
백 스테이지 처리 중...
응답 클 라 이언 트 OK
사용자 입력 대기
Exception in thread "main"java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at tcp.TcpServer.main(TcpServer.java:32)
서버 가 write 를 할 때 문제 가 없 었 다 는 것 을 설명 합 니 다. 다음 read 에서 야 연결 이 끊 겨 비슷 한 이상 을 읽 을 수 없습니다.
왜 일 까요?
어디 썼 지?나 는 특별히 bufferedWriter. flush ();다 괜찮아.
만약 응답 한 것 이 대량의 데이터 라면?아 날로 그 코드 는 다음 과 같 습 니 다.
for(int i=0;i<10000;i++)
sb.append("aaaaaaaaaaaaaa");
bufferedWriter.write(readLine+","+sb.toString());
bufferedWriter.flush();
이때 예 상 했 던 상황 이 왔 다.
tcp 서버 오픈...
소켓 [addr =/127.0.1, port = 3706, localport = 8080] 연결 을 가 져 왔 습 니 다.
클 라 이언 트 정보 수신...
사용자 입력 대기
메시지 수신: aa
백 스테이지 처리 중...
Exception in thread "main"java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:263)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:106)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:190)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:111)
at java.io.BufferedWriter.write(BufferedWriter.java:212)
at java.io.Writer.write(Writer.java:140)
at tcp.TcpServer.main(TcpServer.java:46)
왜 그 럴 까요?캐 시 문제 로 추정 되 며, 구체 적 인 socket 통신 체제 와 관련 이 있 을 수 있 습 니 다.
Socket setSoLinger
Enable/disable SO_LINGER with the specified linger time in seconds. The maximum timeout value is platform specific. The setting only affects socket close.
기본 적 인 상황 에서 close 연결 은 실제 시스템 이 한 동안 머 물 러 야 진정 으로 닫 힐 수 있 습 니 다. 코드 close 는 가상 일 뿐 입 니 다.
구체 적 으로 얼마나 머 무 를 지 는 시스템 플랫폼 에서 결정 된다.앞 에 있 는 write 가 진짜 인가 봐 요. OK.
코드 를 수정 하여 서버 의 처리 시간 을 연장 하 다.다시 해 봐.
System. out. println ("배경 처리 중...");
Thread.sleep(60*1000);
여기 서 1 분 의 상황 을 처리 하 는 것 은 이전 과 마찬가지 로 나 는 2 변 의 통신 방식 이 다음 과 같다 고 추측한다.
서버 에서 write 가 나 왔 을 때 세 번 의 악 수 를 통 해 누군가가 나 에 게 close 를 요청 했다 고 알려 주 었 다. 더 이상 나 에 게 데 이 터 를 보 내지 말 라 고 했다.
이번 수신 은 데이터 의 완전 성 을 확보 하기 위해 서 입 니 다. 제 가 닫 은 후에 바로 다른 socket 이 저 를 사칭 하여 처리 한 데 이 터 를 '사기꾼' 에 게 보 낼 까 봐 걱정 입 니 다.
상대방 에 게 문제 가 생 겼 다 는 것 을 알 게 되 었 습 니 다.
이것 은 단지 추측 일 뿐, 좀 더 검증 이 필요 하 다.
재 테스트
클 라 이언 트 에서 코드 수정
Socket s = new Socket("127.0.0.1", 8080);
s.setSoLinger(true, 0);
close 후 머 무 르 지 않 고 시스템 을 직접 닫 습 니 다.
tcp 서버 오픈...
소켓 [addr =/127.0.1, port = 3842, localport = 8080] 연결 을 가 져 왔 습 니 다.
클 라 이언 트 정보 수신...
사용자 입력 대기
메시지 수신: ff
백 스테이지 처리 중...
Exception in thread "main"java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
at java.io.BufferedWriter.flush(BufferedWriter.java:236)
at tcp.TcpServer.main(TcpServer.java:42)
이때 가 예 상 된 상황 이다.
여기에 또 하나의 문제 가 있 을 수 있 습 니 다. 바로 제 가 클 라 이언 트 에 게 대량의 데 이 터 를 보 낼 때 도 write 의 이상 을 보고 하 는 이 유 는 무엇 입 니까?
코드:
for(int i=0;i<10000;i++)
sb.append("aaaaaaaaaaaaaa");
bufferedWriter.write(readLine+","+sb.toString());
bufferedWriter.flush();
그 이 유 는 그 렇 겠 지.TCP 밑바닥 의 경우 매번 통신 은 가방 을 발송 하 는데 소포 가 너무 크 면 여러 개의 작은 가방 을 낸다
분할 발송, 첫 발송 시 이미 발송 성공 하 였 으 나, 상대방 은 이미 자신 이 닫 힌 상태 로 발송 하 였 습 니 다
서버 가 생 겼 습 니 다. 이때 서버 에서 다시 가방 을 보 내 면 바로 실 패 했 습 니 다.
TCP_NODELAY
SO_TIMEOUT
SO_LINGER
SO_RCVBUF
SO_SNDBUF
TCP 통신 체 제 를 체계적으로 공부 할 시간 이 있 을 것 같 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
자바 소켓 프로 그래 밍텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.