I am coding apps transfer file with LKSCTP. With server receiver file. I
use recvmsg(sk,&inmessage,0). And I want get infomation header of this
packet, but I check inmessage. inmessage.msg_controllen=0, and
inmessage.msg_flags=136. What's 136. In client I just send flags=0. And
msg_control, msg_controllen with full infomation.
And cmsg = CMSG_FIRSTHDR(&inmessage); always return NULL so I can't
write data to file.
Please help me.
I attacth code send_file recv_file. I have checked client. It's ok. But
I don't know why infomation header is NULL.
void recv_file(int sk)
{
char incmsg[CMSG_SPACE(sizeof(_sctp_cmsg_data_t))];
struct iovec iov;
struct msghdr inmessage;
struct cmsghdr *cmsg;
_sctp_cmsg_data_t *sinfo;
int error;
static char buffer[1024];
int buffer_size=1024;
int check_listen;
/* Mark sk as being able to accept new associations */
check_listen = listen(sk, 5);
if (check_listen != 0) {
printf("\n\n\t\tlisten Failure: %s.\n\n\n",
strerror(errno));
exit(1);
}
/* Initialize inmessage with enough space for DATA... */
memset(&inmessage, 0, sizeof(inmessage));
if ((iov.iov_base = malloc(5000)) == NULL) {
printf(" Can't allocate memory.\n");
exit(1);
}
iov.iov_base = buffer;
iov.iov_len = 5000;
inmessage.msg_iov = &iov;
inmessage.msg_iovlen = 1;
/* or a control message. */
inmessage.msg_control = incmsg;
inmessage.msg_controllen = sizeof(incmsg);
int writebyte=0;
int fd[10];
int check_file=0;
for(check_file=0;check_file<count_file;check_file++)
{
fd[check_file] = fopen(localfile[check_file],"w");
if(fd[check_file]==-1)
return;
}
printf(" listening...\n");
/* Get the messages sent */
int time_clock=0;
time_t start, finish;
clock_t start_c, finish_c;
long duration=0;
double duration_c=0;
long temp;
while ((error = recvmsg(sk, &inmessage, MSG_WAITALL))>=0) {
if( !(inmessage.msg_flags & MSG_NOTIFICATION )){
cmsg = CMSG_FIRSTHDR(&inmessage);
if(cmsg==NULL)continue;
sinfo = (struct sctp_sndrcvinfo*)CMSG_DATA(cmsg);
writebyte=fwrite(buffer,error,1,fd[sinfo->sinfo_stream]);
if(time_clock==0)
{
time_clock=1;
start=time(NULL);
start_c=clock();
}
}
else {
union sctp_notification *sn;
sn = (union sctp_notification *)iov.iov_base;
if ((sn->sn_header.sn_type == SCTP_ASSOC_CHANGE) &&
(sn->sn_assoc_change.sac_state
== SCTP_SHUTDOWN_COMP))
break;
}
}
finish=time(NULL);
finish_c=clock();
temp=finish_c-start_c;
duration_c=(double)temp/CLOCKS_PER_SEC;
duration=finish-start;
printf("the file has been transferred in %d secs and %2.3f secs.\n",duration,duration_c);
close(fd);
close(sk);
} /* command_listen() */
oid send_file(int sk)
{
struct msghdr outmsg;
char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
struct cmsghdr *cmsg;
struct sctp_sndrcvinfo *sinfo;
struct iovec iov;
char message[1024];
struct hostent *hst;
struct sockaddr *addrs;
int msglen;
int error = 0;
int try_error=0;
int stream = 0;
//Kiem lai dia chi dich va gan cac thong tin phu hop
if (remote_host != NULL) {
hst = gethostbyname(remote_host);
if (hst == NULL || hst->h_length < 1) {
fprintf(stderr, "%s: bad hostname: \n",
remote_host);
exit(1);
}
ra_family = hst->h_addrtype;
ra_len = sizeof(remote_addr);
ra_raw = &remote_addr.sin_addr;
remote_addr.sin_port = htons(8000);
remote_addr.sin_family = AF_INET;
memcpy(ra_raw, hst->h_addr_list[0], hst->h_length);
}
else
{
//Hostname khong ton tai thoat chuong trinh...
printf("Not found remote host!!!\n");
printf("Shutdown program.\n");
exit(1);
}
printf("Host name is %s.\n",remote_host);
// KIem tra su ton tai cua ket noi toi remote addrs
if ((SOCK_SEQPACKET == socket_type) && associd &&
(0 != test_sk_for_assoc(sk, associd))) {
associd = test_recv_assoc_change(sk);
printf("Old association gone, Starting a new one!\n");
new_connection = 1;
}
int fd[10];
int check_file=0;
for(check_file=0;check_file<count_file;check_file++)
{
if ( localfile[check_file] == NULL ) fd[check_file] = 0;
//fd = open(localfile,O_RDONLY);
fd[check_file] = fopen(localfile[check_file],"r");
if(fd[check_file]==-1)
{
printf("Read file error.\n");
exit(1);
}
printf("Ready to send file....\n");
}
msglen=fread(message,1024,1,fd[0]);
do {
/* Initialize the message struct we use to pass
* messages to the remote socket.
*/
try_error++;
if(try_error==100)
{
printf("Can't connect remote address,program shutdown.\n");
exit(1);
}
iov.iov_base = message;
iov.iov_len = sizeof(message);
outmsg.msg_name=&remote_host;
outmsg.msg_namelen=sizeof(remote_host);
outmsg.msg_iov = &iov;
outmsg.msg_iovlen = 1;
outmsg.msg_control = outcmsg;;
outmsg.msg_controllen = sizeof(outcmsg);
outmsg.msg_name = &remote_addr;
outmsg.msg_namelen = ra_len;
cmsg = CMSG_FIRSTHDR(&outmsg);
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
outmsg.msg_controllen = cmsg->cmsg_len;
sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
memset(sinfo, 0, sizeof(struct sctp_sndrcvinfo));
sinfo->sinfo_flags = 0;
sinfo->sinfo_stream = 0;
error = sendmsg(sk, &outmsg, MSG_WAITALL);
if (error != sizeof(message))
printf(stderr, ": error: %s.\n", strerror(errno));
} while (error != sizeof(message));
/* If this is the first message sent over a UDP-style socket,
* get the associd from the SCTP_ASSOC_CHANGE notification.
*/
if ((SOCK_SEQPACKET == socket_type) && (0 == associd))
associd = test_recv_assoc_change(sk);
/* Verify there is no association. */
if (0 != test_sk_for_assoc(sk, associd)) {
printf("No association is present now!!\n");
new_connection = 1;
}
else {
if (new_connection) {
int rc = sctp_getpaddrs(sk, associd, &addrs);
if (0 >= rc) {
if (rc == 0) {
fprintf(stderr, "sctp_getpaddrs failed, no peers.\n");
} else {
fprintf(stderr, "sctp_getpaddrs failed %s(%d).\n", strerror(errno), errno);
}
exit(1);
}
printf("New connection, peer addresses\n");
//print_addr_buf(addrs, rc);
sctp_freepaddrs(addrs);
new_connection = 0;
}
}
iov.iov_base = buffer;
iov.iov_len = 1;
outmsg.msg_iov = &iov;
outmsg.msg_iovlen = 1;
int end_file[count_file];
for(check_file=0;check_file<count_file;check_file++)
{
end_file[check_file]=0;
}
/* open the file */
time_t start, finish;
clock_t start_c, finish_c;
long duration=0;
double duration_c=0;
long temp;
start=time(NULL);
start_c=clock();
printf("Return code Realy....\n");
while(finished_file<count_file)
{
for(check_file=0;check_file<count_file;check_file++)
{
if(end_file[check_file]==1) continue;
msglen = fread(message,1024,1,fd[check_file]);
if(msglen<=0)
{
end_file[check_file]=1;
finished_file++;
continue;
}
stream=check_file;
sinfo->sinfo_stream = stream;
iov.iov_len = sizeof(message);
error = sendmsg(sk, &outmsg, MSG_WAITALL);
}
}
finish=time(NULL);
finish_c=clock();
temp=finish_c-start_c;
duration_c=(double)temp/CLOCKS_PER_SEC;
duration=finish-start;
//duration=finish-start;
printf("the file has been transferred in %d secs and %2.3f secs.\n",duration,duration_c);
close(fd);
close(sk);
}