나는 C에서 소켓과 TCP 연결을 처리하는 방법을 배우고 있습니다. 기본적으로 서버에서 클라이언트로 또는 그 반대로 시스템 호출을 사용하여 문자 배열을 보내고받는 응용 프로그램 (긴 것)이 있습니다 (두 개의 개별 C 응용 프로그램). 물론이야). 동일한 PC에서 터미널에서 서버를 실행하고 다른 서버에서 클라이언트를 실행하는 로컬 연결로 사용하는 한 모든 것이 잘 작동하고 데이터가 대상에 도착합니다. 그러나 한 컴퓨터의 서버와 다른 컴퓨터의 클라이언트이지만 동일한 인터넷 회선에서 시도하면 192.168.1.X (서버가 실행되는 컴퓨터에서 가져옴)와 같은 주소를 클라이언트에 전달합니다. 연결이 설정되면 예상 바이트 수 (실제 char []를 보내기 전에 전달 함)가 도착하지 않았다는 오류가 표시됩니다.
내가 놓친 것이 있습니다. 일련의 바이트를 순서대로 보내는 데 제한이 있습니까?
오류가 발생한 코드입니다.
서버 측:
r=htonl(lghstr);
w=write(myFd,&r,sizeof(int));//writes the number of incoming bytes
if(w<0) perror("writeServer4"),exit(-1);
w=write(myFd,tmp->string,lghstr);
if(w<0) perror("writeServer5"),exit(-1);
if(w!=lghstr) perror("ERROR");
고객 입장에서
rC=read(fdc,&cod,sizeof(int));//read incoming number of bytes
lghstr=ntohl(cod);
if(rC<0) perror("readClient3"),exit(-1);
rC=read(fdc,dest,lghstr);
if(rC<0) perror("readClient4"),exit(-1);
if(rC!=lghstr) perror("error : "), printf("didn't read the right number of bytes"),exit(-1);
이제 이것은 기본적으로 여러 번 반복됩니다. 심지어 300 번이라고합시다. 큰 숫자로 인해 프로그램이 작동하지 않습니다.
이게 문제 야:
rC=read(fdc,dest,lghstr);
...
if(rC!=lghstr) perror("error : ")
소켓 프로그래밍과 함께 # 1 착오가 있음을 기대 recv()
하고 read()
정확히 반대편에 의한 쓰기 / 전송 호출에 해당하는 바이트의 같은 수를 반환합니다.
실제로 부분 데이터는 매우 가능성이 높고 예상됩니다. 간단한 해결 방법은 예상되는 정확한 바이트 수를 얻을 때까지 읽기 / 받기를 반복하는 것입니다.
size_t count = 0;
while (count < lghstr)
{
ssize_t readresult = read(fdc, dest+count, lghstr-count);
if (readresult == -1)
{
// socket error - handle appropriately (typically, just close the connection)
}
else if (readresult == 0)
{
// The other side closed the connection - handle appropriately (close the connection)
}
else
{
count += readresult;
}
}
루핑의 다른 대안은 소켓과 함께 MSG_WAITALL 플래그를 사용하는 것입니다. 이것은 read () 대신 recv ()를 사용하는 것을 의미합니다. 여전히 오류 사례를 처리해야합니다.
rc = recv(fdc, dest, lghstr, MSG_WAITALL);
if (rc == -1)
{
// socket error
}
else if (rc == 0)
{
// socket closed by remote
}
else if (rc < lghstr)
{
// the other side likely closed the connection and this is residual data (next recv will return 0)
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다