Updates to Nread/Nwrite in net.c

This commit is contained in:
sethdelliott 2010-06-28 22:25:03 +00:00
parent 4f43111900
commit fd10304cbd
5 changed files with 117 additions and 64 deletions

View File

@ -141,6 +141,9 @@ struct iperf_test
int reporter_interval; int reporter_interval;
void (*stats_callback) (struct iperf_test *); void (*stats_callback) (struct iperf_test *);
void (*reporter_callback) (struct iperf_test *); void (*reporter_callback) (struct iperf_test *);
/* result string */
char *result_str;
int reporter_fd; /* file descriptor for reporter */ int reporter_fd; /* file descriptor for reporter */
int num_streams; /* total streams in the test (-P) */ int num_streams; /* total streams in the test (-P) */

View File

@ -378,6 +378,53 @@ iperf_exchange_parameters(struct iperf_test * test)
return 0; return 0;
} }
/*************************************************************/
int
iperf_exchange_results(struct iperf_test *test)
{
size_t len;
uint32_t nlen;
int tlen;
char *sbuf;
if (test->result_str == NULL)
return 0;
if (test->role == 'c') {
len = strlen(test->result_str);
sbuf = (char *) malloc(len*sizeof(char) + sizeof(nlen));
nlen = htonl(len);
memcpy(sbuf, &nlen, sizeof(nlen));
memcpy(sbuf+sizeof(nlen), test->result_str, len);
tlen = len + sizeof(nlen);
len = 0;
while (tlen) {
if ((len += write(test->ctrl_sck, sbuf + len, tlen)) < 0) {
perror("write results client");
return -1;
}
tlen -= len;
}
// Need to read
} else {
}
return 0;
}
/*************************************************************/ /*************************************************************/
/** /**
* add_to_interval_list -- adds new interval to the interval_list * add_to_interval_list -- adds new interval to the interval_list
@ -513,6 +560,7 @@ iperf_defaults(struct iperf_test * testp)
testp->stats_interval = 0; testp->stats_interval = 0;
testp->reporter_interval = 0; testp->reporter_interval = 0;
testp->num_streams = 1; testp->num_streams = 1;
testp->result_str = NULL;
testp->default_settings->unit_format = 'a'; testp->default_settings->unit_format = 'a';
testp->default_settings->socket_bufsize = 0; /* use autotuning */ testp->default_settings->socket_bufsize = 0; /* use autotuning */

View File

@ -159,7 +159,8 @@ iperf_tcp_accept(struct iperf_test * test)
return -1; return -1;
} }
setnonblocking(peersock); // XXX: Nonblocking off. OKAY since we use select.
// setnonblocking(peersock);
sp = test->new_stream(test); sp = test->new_stream(test);
sp->socket = peersock; sp->socket = peersock;

107
src/net.c
View File

@ -102,75 +102,76 @@ Nread(int fd, char *buf, int count, int prot)
{ {
struct sockaddr from; struct sockaddr from;
socklen_t len = sizeof(from); socklen_t len = sizeof(from);
register int cnt; register int n;
register int nleft = count;
if (prot == SOCK_DGRAM) { if (prot == SOCK_DGRAM) {
cnt = recvfrom(fd, buf, count, 0, &from, &len); // XXX: Does recvfrom guarantee all count bytes are sent at once?
fprintf(stderr, "READING UDP DATA IN Nread SOCK_DGRAM\n");
n = recvfrom(fd, buf, count, 0, &from, &len);
} else { } else {
cnt = mread(fd, buf, count); while (nleft > 0) {
if ((n = read(fd, buf, nleft)) < 0) {
if (errno == EINTR)
n = 0;
else
return (-1);
} else if (n == 0)
break;
nleft -= n;
buf += n;
}
} }
return (cnt); return (count - nleft);
} }
/* /*
* N W R I T E * N W R I T E
*
* XXX: After updating this function to use read/write, the only difference between
* TCP and UDP is that udp handles ENOBUFS. Should we merge the two?
*/ */
int int
Nwrite(int fd, char *buf, int count, int prot) Nwrite(int fd, char *buf, int count, int prot)
{ {
register int cnt; register int n;
if (prot == SOCK_DGRAM) /* UDP mode */ register int nleft = count;
{
again: if (prot == SOCK_DGRAM) { /* UDP mode */
cnt = send(fd, buf, count, 0); while (nleft > 0) {
if (cnt < 0 && errno == ENOBUFS) if ((n = write(fd, buf, nleft)) < 0) {
{ if (errno == EINTR) {
/* wait if run out of buffers */ n = 0;
/* XXX: but how long to wait? Start shorter and increase delay each time?? */ } else if (errno == ENOBUFS) {
delay(18000); /* XXX: Fixme! */ /* wait if run out of buffers */
errno = 0; /* XXX: but how long to wait? Start shorter and increase delay each time?? */
goto again; delay(18000); // XXX: Fixme!
} n = 0;
} else } else {
{ return (-1);
//printf("Nwrite: writing %d bytes to socket %d \n", count, fd); }
cnt = write(fd, buf, count); }
nleft -= n;
buf += n;
}
} else {
while (nleft > 0) {
if ((n = write(fd, buf, nleft)) < 0) {
if (errno == EINTR)
n = 0;
else
return (-1);
}
nleft -= n;
buf += n;
}
} }
//printf("Nwrite: wrote %d bytes \n", cnt); return (count);
return (cnt);
} }
/*
* mread: keep reading until have expected read size
*/
int
mread(int fd, char *bufp, int n)
{
register unsigned count = 0;
register int nread;
do
{
nread = read(fd, bufp, n - count);
if (nread < 0) /* if get back -1, just keep trying */
{
continue;
} else
{
//printf("mread: got %d bytes \n", nread);
if (nread == 0)
return ((int) count);
count += (unsigned) nread;
bufp += nread;
}
} while (count < n);
return ((int) count);
}
/*************************************************************************/ /*************************************************************************/
/** /**

View File

@ -1,13 +1,13 @@
int netdial(int proto, char *client, int port); #ifndef __NET_H
int netannounce(int proto, char *local, int port); #define __NET_H
int Nwrite(int fd, char *buf, int count, int prot);
int mread(int fd, char *bufp, int n);
int Nread(int fd, char *buf, int count, int prot);
int getsock_tcp_mss(int inSock);
int set_tcp_options(int sock, int no_delay, int mss);
int setnonblocking(int sock);
int netdial(int, char *, int);
int netannounce(int, char *, int);
int Nwrite(int, char *, int, int);
int Nread(int, char *, int, int);
int getsock_tcp_mss(int);
int set_tcp_options(int, int, int);
int setnonblocking(int);
#endif