2017-10-08 5 views
0

완전히 투명하기 만하면됩니다. 첫 번째소켓 용 버퍼링 된 리더가 준비되지 않음

  1. 노드 A 텍스트 파일
  2. 노드 A가 전송
  3. 텍스트 파일에서 읽기 (마이너스 :

    는 할 더있다,하지만 지금 난 그냥 다음 얻으려고 라인)

  4. 노드 B는 말했다 소켓에서 읽어 소켓을 사용하여 B를 노드로, 콘솔

에 인쇄 그것을 밖으로 그러나 지금은 정보 하나가 전송되지 않는 것 같습니다, 또는 그것은 상응하는 것으로 읽히지 않는다. ctly 노드 B에 의해

내 메인 클래스에서

, 나는이 같은 노드 설정 :

NodeA nodeA = new NodeA(); 
NodeB nodeB = new NodeB(); 

new Thread(nodeA).start(); 
new Thread(nodeB).start(); 

노드 A에서를, 나는 이렇게 :

//Open a socket for talking with NodeB 
Socket mySocket = new Socket(InetAddress.getLocalHost(), portNum); 

//Set up the socket's output 
PrintWriter out = new PrintWriter(mySocket.getOutputStream(), true); 

//Loop through the lines of the confA file, writing them to the socket 
String line = bufferedReader.readLine(); 
while (line != null) 
{ 
    //Write the line to the socket, get the next line 
    out.println(line); //updated to println, this flushes and fixes another problem 
    out.flush(); 
    line = bufferedReader.readLine(); 
} 

//Close the socket 
mySocket.close(); 

주를 그 노드 A의 루프 작품 벌금. 영원히 반복하지 않으며 인쇄 문을 테스트 할 때 의도 한 텍스트 행을 반복합니다.

그런 다음, 노드 B의 끝에 : 현재 노드 B 코드 in.ready 그러나

//Open the socket 
ServerSocket mySocket = new ServerSocket(portNum); 
Socket connectionSocket = mySocket.accept(); 

//Set up a reader on the socket to get what's coming from it 
BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream())); 

String line = in.readLine(); //hang occurs here 

while(line != null) { 
    System.out.println(line); 
    line = in.readLine();; 
} 

에게, 보여 업데이트 () 결코 사실이다. 나는 while 루프를 사용하여 그 일이 일어나기를 기다리려고했지만 결코 발생하지 않습니다.

저는 이유가 확실하지 않습니다. 정확히 바르게 설정하면 소켓을 제대로 설정했는지 전혀 알지 못합니다.

나는 A를 듣고있는 서버에 B를 만드는 것이 가장 합리적이라고 생각했습니다. . 나는 그것이 옳기를 바랍니다. 그것은 내가 SO에 대한 몇 가지 다른 예를 본 것과 비슷하게 보입니다.

감사합니다. 나는 소켓, 포트, 듣기 등등에 익숙하지 않기 때문에 처음에는 당신의 제안을 이해하지 못한다면 나를 용서해주십시오. 내가 간다는 것을 이해하기 위해 최선을 다할 것입니다.

문제가있는 곳에서 더 읽기 쉽고 명확하게 코드를 작성하는 것을 자제했으나 자세한 정보가 필요하면 언제든지 물어보십시오. 제공 해드릴 수 있도록 최선을 다할 것입니다.

+0

1)'ServerSocket.accept()'가 돌아올 때마다 서버와 클라이언트 사이에 연결된 소켓이 있습니다. 연결에 대해서는'ServerSocket.accept()'를 다시 호출하지 않습니다. 2) 클라이언트에서 PrintWriter는 데이터를 내부적으로 버퍼링합니다. 'out.print (line);을 호출 한 결과를 즉시 네트워크에서 볼 수있게하려면 다음 문으로 out.flush()를 호출해야합니다. –

+0

'ready()'는 다음 읽기가 즉시 리턴 될지 여부를 리턴합니다. [설명서] (https://docs.oracle.com/javase/9/docs/api/java/io/Reader.html#ready--)를 참조하십시오. – VGR

답변

2

서버는 먼저 ServerSocket에서 클라이언트로 소켓을 가져와야합니다.

connectionSocket = mySocket.accept(); 

클라이언트가 connectionSocket을 허용 할 때까지 서버 스레드는 잠자기 상태가됩니다.

당신은 connectionSocket에서 읽을 수 있습니다. ready이 필요하지 않습니다.

이것은 과제물이므로 나머지는 남겨 둡니다.


는 그런데 일반적인 서버 할 것 :

for (;;) { 
    Socket socket = serverSocket.accept(); 
    ... pass the socket to a thread from a pool of threads 
} 
+0

응답 해 주셔서 감사합니다.하지만 몇 가지 사항이 여전히 매우 혼란 스럽습니다. 서버가 대기하고 클라이언트가 연결되면 다른 .accept()를 수행 할 필요가 없습니다. 맞습니까? 초기 코드 인 .accept 만 갖기 위해 코드를 변경해 보았습니다.하지만 여전히 소켓에서 읽을 수없는 것처럼 보입니다. readLine()은 영원히 멈 춥니 다. –

+1

읽기 전용 소켓을 생성하는'ServerSocket.accept'가 하나만 있어야합니다. –

+0

감사합니다. 나는 여분의 .accepts()를 제거한 코드를 .ready()의 제거로 업데이트하고 현재 중단이 발생한 위치를 보여줍니다. –

1

나는 문제가 준비가 당신이 읽기를 호출하는 경우는 차단하지 않습니다 것을 의미라고 생각합니다. 당신이 grepcode의 기능을 보면 당신이 실행됩니다 코드를 볼 수 있습니다

http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/io/BufferedReader.java#BufferedReader.ready%28%29

준비된 스레드는 당신이 확인하고자 할 때 유용하다 차단하지 않을 것 즉, 스레드의 ISN ' 묶여 버릴 테지만, 버퍼가 있는지 없는지는 실제로 알려주지 않습니다.

데이터를 소비 할 때까지 읽기 호출을 차단 호출로 수행하면됩니다. 이 스레드가 현재 스레드를 차단하지 않게하려면 차단할 수있는이 읽기 전용 새 소비자 스레드를 스핀 오프하십시오.

또한 닫힌 소켓 또는 플러시로 보내기 통신이 끝나면 소비 스트림을 완료 할 때 알려줍니다. 그리고 당신은 오픈/클로즈 세션 당 한 번만 소켓 수용을 할 필요가 있습니다.

+0

나는 현재 스레드를 읽지 않아도 상관 없다. 전혀 문제가되지 않아야한다. 나는 오직 하나의 .accept()를 처음에 가지고 코드를 변경하여 in.ready()를 변경하여 readLine()에서 반환 된 라인이 null이 아닌지 확인했다. 그것은 아직 시도하고있는 초기 readLine()에 걸려있다. –

+0

Readline은 문자열 끝을 요구합니다. \ n EOL 또는 닫힌 소켓을 찾고 있습니다. 중단되면 더 많은 데이터를 기다리고 있음을 의미합니다. 서면 끝에 작성자의 소켓을 닫아 확인할 수 있습니다. – user1442498

+0

고맙습니다. mySocket.close(); 노드 A의 코드 끝에. 아직 행운이 없습니다. 다른 쪽 끝을 닫아야합니까? –

관련 문제