recvmsg 및 sendmsg를 사용하여 비동기 STREAM 소켓을 통해 데이터를 전송합니다. 전송할 데이터의 양은 15MB에서 30MB 사이에서 상당히 큽니다.recvmsg linux 잘못된 데이터 수신
왜 데이터가 손상되었는지 이해할 수 없습니다. 보내는 메시지와 reciving 함수는 errno EINTR 및 EAGAIN에 의해 인터럽트됩니다. 내가 사용 석사
기능은 다음과 같습니다 반복적으로 데이터 버퍼 경우의 시작 부분에 같은 접두사/RECV를 보낼 수 있도록
이int receive_result_with_extra(int fd, struct syscall_result * result, int extra_size, char * buf) {
struct iovec io[2];
struct msghdr msg;
int transfered=0, temp=0;
const int total = SIZE_RESULT + extra_size;
CLEAN_MSG(&msg);
memset(io, 0, sizeof(io));
// result header
io[1].iov_len=SIZE_RESULT;
io[1].iov_base=result;
// result buffer
io[0].iov_len = extra_size;
io[0].iov_base = buf;
// iov struct
msg.msg_iov=io;
msg.msg_iovlen=2;
do {
temp = recvmsg(fd,&msg, 0);
if (temp < 0 && (errno==EAGAIN || errno == EINTR || errno == EWOULDBLOCK))
continue;
else if (temp < 0)
die("Error receiveing data recvmsg (receive_result_with_extra)");
transfered += temp;
} while(transfered < total);
if (transfered < 0)
die("recvmsg (receive_result_with_extra)");
assert(transfered == total);
return transfered;
}
int send_result_with_extra(int fd, struct syscall_result * result, int extra_size, char * buf) {
struct iovec io[2];
struct msghdr msg;
int transfered=0, temp=0;
const int total = SIZE_RESULT + extra_size;
CLEAN_MSG(&msg);
memset(io, 0, sizeof(io));
// result header
io[1].iov_len=SIZE_RESULT;
io[1].iov_base=result;
// result buffer
io[0].iov_len = extra_size;
io[0].iov_base = buf;
// iov struct
msg.msg_iov=io;
msg.msg_iovlen=2;
do {
temp=sendmsg(fd,&msg, 0);
if (temp < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
continue;
else if (temp < 0)
die("Failed sending data (send_result_with_extra)");
transfered += temp;
} while(transfered < total);
if (transfered < 0)
die("recvmsg (fstat handler)");
assert(transfered == total);
return transfered;
}
나는 의심의 여지 왜 recvmsg'의 마지막 인수'0' (FD, MSG, 0);'나는 그것이를 sizeof msg' –
@GrijeshChauhan 아니 그것, 그것은 맞습니다 것 플래그 값 '해야한다고 생각합니다. –
@JoachimPileborg는'struct msghdr'가 미리 정의 된 구조체임을 의미합니다. –