2012-01-25 5 views
1

기본 TCP 클라이언트/서버 프로그램이 있습니다.내 TCP 코드에서 읽기/쓰기가 작동하지 않습니다.

나는 클라이언트와 읽고 쓰는 서버 모두에 메소드가 있습니다. 그것은 완벽하게 내가 그것을 처음 실행할 때 작동하지만, 다시 실행하면 그것은 아무것도 읽지 않습니다 (이 루프에서의). 서버

void printout(char buffer[], int sockfd) { 
bzero(buffer, 256); 
n = read(sockfd, buffer, 256); 
printf("%s\n", buffer); 
n = read(sockfd, buffer, 256); 
printf("%s\n", buffer); 
n = read(sockfd, buffer, 256); 
printf("%s\n", buffer); 
n = read(sockfd, buffer, 256); 
printf("%s\n", buffer); 
n = read(sockfd, buffer, 256); 
printf("%s\n", buffer); 
} 

A2에서

void printout(int newsockfd, char buffer) { 
n = write(newsockfd, a2, 256); 
n = write(newsockfd, a3, 256); 
n = write(newsockfd, a4, 256); 
n = write(newsockfd, a5, 256); 
n = write(newsockfd, a6, 256); 
} 

를, A3, a4, a5 및 a6은 문자열입니다. 처음 실행하면 모든 것을 올바르게 인쇄합니다. 두 번째로 아무 것도 출력하지 않고 빈 줄 하나만 인쇄합니다. 버퍼가 무엇인지 알아보기 위해 테스트했을 때, 나는 그 버퍼를 ""얻었다. 문제가 무엇인지 또는 어떻게 해결할 수 있는지 알고 있습니까?

+0

각'write' 호출 후에'n'의 값을 출력하고'read'를 호출 할 때마다'n'의 값을 출력 해 봅니다. 'n'이 0보다 작 으면'errno'의 값을 출력하십시오. –

+0

코드는'read'의 반환 값을 무시하므로 얼마나 많은 바이트를 받았는지 알 수 없습니다. 또한 네트워크를 통해 수신 된 임의의 바이트를 C 스타일 문자열로 처리 할 수 ​​없습니다. –

+0

모든 호출 후에 n이 256이라고 ... –

답변

3

우리가 루프를 보여주지 않으므로 문제를 찾아내는 것이 어렵습니다.

그러나 한 가지 점은 write()에 대한 모든 호출이 read()에 대한 호출과 일치 할 것으로 예상하는 것입니다. 이것은 TCP가 작동하는 방식이 아닙니다. 패킷이 단편화되거나 부분 읽기 등이 발생할 수 있습니다. 즉, TCP는 stream protocol이고 은 메시지 지향형이 아닙니다입니다.

특히, read()이 256 바이트 미만을 반환하는 상황을 처리 할 준비가되어 있어야합니다. 언제든지 귀하의 read() 통화 중 하나에 발생할 수 있습니다.

또한 C 문자열로 256 바이트의 청크를 처리하기 때문에 서버가 클라이언트에 의존하지 않고 자체 NUL 터미네이터를 추가하는 것이 현명합니다.

+0

코드 길이가 400 라인을 넘습니다. 기본적으로 while 루프 while (1> 0) {printout(); 클라이언트와 서버 모두에서 다른 것들을 많이} 사용할 수 있습니다. l은 매 턴마다 감소합니다.일치하는 읽기/쓰기를 얻으려면 어떻게해야합니까? –

+2

읽기 및 쓰기가 지정된 바이트 수의 읽기/쓰기를 보장하지 않기 때문에 지정된 바이트 수가 읽히거나 쓰여질 때까지 계속 호출하는 읽기 및 쓰기 용 래퍼를 작성하는 것이 좋습니다. 다른 접근법이 있지만 나머지 코드는 보지 않고 다른 접근법을 추천하기는 어렵습니다. – Klox

0

두 번째 실행시 서버의 bind() 호출에 실패했습니다. 클라이언트가 connect()을 호출합니다. 그것들에 대한 오류 처리가 있습니까? 서버가 사망 한 후 서버의 첫 번째 실행은 잠시 동안 포트에 "잡아"하는 EDIT

간단한 TCP 예제를하고 특히, 드문 일이 아니에요. 서버를 다시 실행할 때 bind()이 실패하므로 서버 프로세스는 listen() 또는 accept()의 새 연결을 수행 할 수 없습니다. 세부 사항을 설명하는 것은 다른 질문의 주제입니다.

서버가 실제로 존재하지 않으므로 클라이언트에서 connect()이 실패하고 연결되지 않은 소켓이 남습니다. 그리고 그 소켓으로부터의 모든 후속 읽기들은 즉시 실패 할 것이고, 0을 모두 포함하는 buffer을 남긴다. 이것은 당신이 보는 행동에 대한 가능한 설명 일 것입니다.

이 설명을 다룰 수 있습니까? bind()connect()이 항상 0을 반환하는지 확인 하시겠습니까?

+0

바인드 및 연결 호출은 주에 있으므로 한 번만 발생합니다. 틀렸어? –

+0

@BM : 내 답변에 정교함을 추가했습니다. – Managu

+0

죄송합니다,'connect()'에 대해 잘못된 행동을했습니다. 그것을 바꿨다. – Managu

관련 문제