void handle_socket_error(osi_socket so) { struct msghdr msg; struct cmsghdr *cmsg; struct sock_extended_err *err; struct sockaddr_in addr; struct sockaddr *offender; char *controlmsgbuf; int code; struct socket *sop = (struct socket *)so; if (!(controlmsgbuf=rxi_Alloc(256))) return; msg.msg_name = &addr; msg.msg_namelen = sizeof(addr); msg.msg_control = controlmsgbuf; msg.msg_controllen = 256; msg.msg_flags = 0; code = kernel_recvmsg(sop, &msg, NULL, 0, 0, MSG_ERRQUEUE|MSG_DONTWAIT|MSG_TRUNC); if (code < 0 || !(msg.msg_flags & MSG_ERRQUEUE)) goto out; for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (CMSG_OK(&msg, cmsg) && cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) break; } if (!cmsg) goto out; err = CMSG_DATA(cmsg); offender = SO_EE_OFFENDER(err); if (offender->sa_family != AF_INET) goto out; memcpy(&addr, offender, sizeof(addr)); if (err->ee_origin == SO_EE_ORIGIN_ICMP && err->ee_type == ICMP_DEST_UNREACH && err->ee_code == ICMP_FRAG_NEEDED) { rxi_SetPeerMtu(NULL, ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), err->ee_info); } /* other DEST_UNREACH's and TIME_EXCEEDED should be dealt with too */ out: rxi_Free(controlmsgbuf, 256); return; }
/** * return: * 0 if no error * 1 if TTL exceeded * >1 if other icmp-like error */ static int handleRecvErrSEE(struct sock_extended_err *see, int returnttl, const char *tos, double lastPingTime) { int isicmp = 0; int ret = 0; if (!see) { fprintf(stderr, "%s: Error, but no error info\n", argv0); return ret; } /* print "From ...: */ if (see->ee_origin == SO_EE_ORIGIN_LOCAL) { printf("From local system: "); } else { struct sockaddr *offender = SO_EE_OFFENDER(see); char abuf[NI_MAXHOST]; int err; if (offender->sa_family == AF_UNSPEC) { if (!options.traceroute) { printf("From "); } printf("<unknown>: "); } else if ((err = getnameinfo(offender, sizeof(struct sockaddr_storage), abuf, NI_MAXHOST, NULL, 0, NI_NUMERICHOST))) { fprintf(stderr, "%s: getnameinfo(): %s\n", argv0, gai_strerror(err)); if (!options.traceroute) { printf("From "); } printf("<unknown>"); if (tos) { printf(" %s", tos); } if (returnttl > 0) { printf(" ttl=%d", returnttl); } printf(": "); } else { if (!options.traceroute) { printf("From "); } printf("%s", abuf); if (tos) { printf(" %s", tos); } if (returnttl > 0) { printf(" ttl=%d", returnttl); } if (lastPingTime) { printf(" time=%.2f ms", 1000*(clock_get_dbl()-lastPingTime)); } printf(": "); } } if (see->ee_origin == SO_EE_ORIGIN_ICMP6 || see->ee_origin == SO_EE_ORIGIN_ICMP) { isicmp = 1; } /* Print error message */ switch (see->ee_errno) { case ECONNREFUSED: printf("Port closed"); ret = 2; break; case EMSGSIZE: printf("PMTU %d", see->ee_info); ret = 2; break; case EPROTO: printf("Protocol error"); ret = 2; break; case ENETUNREACH: printf("Network unreachable"); ret = 2; break; case EACCES: printf("Access denied"); ret = 2; break; case EHOSTUNREACH: if (isicmp && see->ee_type == 11 && see->ee_code == 0) { printf("TTL exceeded"); ret = 1; } else { printf("Host unreachable"); ret = 2; } break; default: printf("%s", strerror(see->ee_errno)); ret = 2; break; } icmpError++; if (options.verbose && (0 < returnttl)) { printf(". return TTL: %d.", returnttl); } printf("\n"); return ret; }
/** Process UDP error event. */ int tport_udp_error(tport_t const *self, su_sockaddr_t name[1]) { struct cmsghdr *c; struct sock_extended_err *ee; su_sockaddr_t *from; char control[512]; char errmsg[64 + 768]; struct iovec iov[1]; struct msghdr msg[1] = {{ 0 }}; int n; msg->msg_name = name, msg->msg_namelen = sizeof(*name); msg->msg_iov = iov, msg->msg_iovlen = 1; iov->iov_base = errmsg, iov->iov_len = sizeof(errmsg); msg->msg_control = control, msg->msg_controllen = sizeof(control); n = recvmsg(self->tp_socket, msg, MSG_ERRQUEUE); if (n < 0) { int err = su_errno(); if (!su_is_blocking(err)) SU_DEBUG_1(("%s: recvmsg: %s\n", __func__, su_strerror(err))); return 0; } if ((msg->msg_flags & MSG_ERRQUEUE) != MSG_ERRQUEUE) { SU_DEBUG_1(("%s: recvmsg: no errqueue\n", __func__)); return 0; } if (msg->msg_flags & MSG_CTRUNC) { SU_DEBUG_1(("%s: extended error was truncated\n", __func__)); return 0; } if (msg->msg_flags & MSG_TRUNC) { /* ICMP message may contain original message... */ SU_DEBUG_3(("%s: icmp(6) message was truncated (at %d)\n", __func__, n)); } /* Go through the ancillary data */ for (c = CMSG_FIRSTHDR(msg); c; c = CMSG_NXTHDR(msg, c)) { if (0 #if HAVE_IP_RECVERR || (c->cmsg_level == IPPROTO_IP && c->cmsg_type == IP_RECVERR) #endif #if HAVE_IPV6_RECVERR || (c->cmsg_level == IPPROTO_IPV6 && c->cmsg_type == IPV6_RECVERR) #endif ) { char info[128]; char const *origin; ee = (struct sock_extended_err *)CMSG_DATA(c); from = (su_sockaddr_t *)SO_EE_OFFENDER(ee); info[0] = '\0'; switch (ee->ee_origin) { case SO_EE_ORIGIN_LOCAL: origin = "local"; break; case SO_EE_ORIGIN_ICMP: origin = "icmp"; snprintf(info, sizeof(info), " type=%u code=%u", ee->ee_type, ee->ee_code); break; case SO_EE_ORIGIN_ICMP6: origin = "icmp6"; snprintf(info, sizeof(info), " type=%u code=%u", ee->ee_type, ee->ee_code); break; case SO_EE_ORIGIN_NONE: origin = "none"; break; default: origin = "unknown"; break; } if (ee->ee_info) snprintf(info + strlen(info), sizeof(info) - strlen(info), " info=%08x", ee->ee_info); SU_DEBUG_3(("%s: %s (%d) [%s%s]\n", __func__, su_strerror(ee->ee_errno), ee->ee_errno, origin, info)); if (from->su_family != AF_UNSPEC) SU_DEBUG_3(("\treported by [%s]:%u\n", su_inet_ntop(from->su_family, SU_ADDR(from), info, sizeof(info)), ntohs(from->su_port))); if (msg->msg_namelen == 0) name->su_family = AF_UNSPEC; SU_CANONIZE_SOCKADDR(name); return ee->ee_errno; } } return 0; }
int NET_GetPacket (netsrc_t sock, netadr_t *net_from, sizebuf_t *net_message) { if (NET_GetLoopPacket (sock, net_from, net_message)) return 1; int net_socket = ip_sockets[sock]; if (!net_socket) return 0; struct sockaddr_in from; uint32 fromlen = sizeof(from); int ret = recvfrom (net_socket, net_message->data, net_message->maxsize , 0, (struct sockaddr *)&from, &fromlen); if (ret == -1) { //linux makes this needlessly complex, couldn't just return the source of the error in from, oh no... struct probehdr rcvbuf; struct iovec iov; struct msghdr msg; struct cmsghdr *cmsg; char cbuf[1024]; #ifdef SOCK_EXTENDED_ERR struct sock_extended_err *e; #endif // SOCK_EXTENDED_ERR int err = errno; memset (&rcvbuf, 0, sizeof(rcvbuf)); iov.iov_base = &rcvbuf; iov.iov_len = sizeof (rcvbuf); memset (&from, 0, sizeof(from)); msg.msg_name = (void *)&from; msg.msg_namelen = sizeof (from); msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_flags = 0; msg.msg_control = cbuf; msg.msg_controllen = sizeof (cbuf); for (;;) { ret = recvmsg (net_socket, &msg, MSG_ERRQUEUE); if (ret == -1) { if (errno == EWOULDBLOCK || errno == EAGAIN) { if (err == EWOULDBLOCK || err == EAGAIN) { return 0; } else { errno = err; Com_Printf ("NET_GetPacket: %s\n", LOG_NET, NET_ErrorString()); return 0; } } else { Com_DPrintf ("NET_GetPacket: recvmsg(): %s\n", NET_ErrorString()); return 0; } } else if (!ret) { Com_DPrintf ("NET_GetPacket: recvmsg(): EOF\n"); return 0; } errno = err; Com_DPrintf ("NET_GetPacket: Called recvmsg() for extended error details for %s\n", NET_ErrorString()); //linux 2.2 (maybe others) fails to properly fill in the msg_name structure. Com_DPrintf ("(msgname) family %d, host: %s, port: %d, flags: %d\n", from.sin_family, inet_ntoa (from.sin_addr), from.sin_port, msg.msg_flags); #ifdef SOCK_EXTENDED_ERR e = NULL; for (cmsg = CMSG_FIRSTHDR (&msg); cmsg; cmsg = CMSG_NXTHDR (&msg, cmsg)) { if (cmsg->cmsg_level == SOL_IP) { if (cmsg->cmsg_type == IP_RECVERR) { e = (struct sock_extended_err *) CMSG_DATA (cmsg); } else Com_DPrintf ("cmsg type = %d\n", cmsg->cmsg_type); } } if (!e) { Com_DPrintf ("NET_GetPacket: recvmsg(): no extended info available\n"); continue; } if (e->ee_origin == SO_EE_ORIGIN_ICMP) { //for some unknown reason, the kernel zeroes out the port in SO_EE_OFFENDER, so this is pretty much useless struct sockaddr_in *sin = (struct sockaddr_in *)SO_EE_OFFENDER(e); Com_DPrintf ("(ICMP) family %d, host: %s, port: %d\n", sin->sin_family, inet_ntoa (sin->sin_addr), sin->sin_port); //but better than nothing if using buggy kernel? if (from.sin_family == AF_UNSPEC) { memcpy (&from, sin, sizeof(from)); //can't trust port, may be buggy kernel (again) from.sin_port = 0; } } else { Com_DPrintf ("NET_GetPacket: recvmsg(): error origin is %d\n", e->ee_origin); continue; } SockadrToNetadr (&from, net_from); switch (e->ee_errno) { case ECONNREFUSED: case EHOSTUNREACH: case ENETUNREACH: Com_Printf ("NET_GetPacket: %s from %s\n", LOG_NET, strerror(e->ee_errno), NET_AdrToString (net_from)); if (net_ignore_icmp->intvalue) return 0; else return -1; default: Com_Printf ("NET_GetPacket: %s from %s\n", LOG_NET, strerror(e->ee_errno), NET_AdrToString (net_from)); continue; } #endif // SOCK_EXTENDED_ERR } //errno = err; //Com_Printf ("NET_GetPacket: %s\n", LOG_NET, NET_ErrorString()); return 0; } net_packets_in++; net_total_in += ret; SockadrToNetadr (&from, net_from); if (ret == net_message->maxsize) { Com_Printf ("Oversize packet from %s\n", LOG_NET, NET_AdrToString (net_from)); return 0; } net_message->cursize = ret; return 1; }
int main(int argc, char *argv[]) { printf("SOCK_RAW=%u\n", SOCK_RAW); printf("SOCK_STREAM=%u\n", SOCK_STREAM); printf("SOCK_DGRAM=%u\n", SOCK_DGRAM); printf("IPPROTO_ICMP=%u\n", IPPROTO_ICMP); printf("IPPROTO_TCP=%u\n", IPPROTO_TCP); printf("IPPROTO_IP=%u\n", IPPROTO_IP); int sock; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int addr_len = sizeof(struct sockaddr); int numbytes; //struct hostent *host; int send_len = 200000; char send_data[send_len + 24]; int port; int client_port; pid_t pID; memset(send_data, 89, send_len); send_data[send_len] = '\0'; //host= (struct hostent *) gethostbyname((char *)"127.0.0.1"); //if ((sock = socket(PF_INET, SOCK_RAW, IPPROTO_UDP)) == -1) { //if ((sock = socket(PF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1) { if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) == -1) { perror("socket"); exit(1); } int val = 0; setsockopt(sock, SOL_IP, IP_MTU_DISCOVER, &val, sizeof(val)); val = 1; setsockopt(sock, SOL_SOCKET, SO_TIMESTAMP, &val, sizeof(val)); val = 1; setsockopt(sock, SOL_IP, IP_RECVTTL, &val, sizeof(val)); val = 1; setsockopt(sock, SOL_IP, IP_RECVERR, &val, sizeof(val)); //fcntl64(3, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 //fstat64(1, {st_dev=makedev(0, 11), st_ino=3, st_mode=S_IFCHR|0620, st_nlink=1, st_uid=1000, st_gid=5, st_blksize=1024, st_blocks=0, st_rdev=makedev(136, 0), st_atime=2012/10/16-22:31:09, st_mtime=2012/10/16-22:31:09, st_ctime=2012/10/16-19:33:02}) = 0 val = 3; setsockopt(sock, SOL_IP, IP_TTL, &val, sizeof(val)); if (argc > 1) { port = atoi(argv[1]); } else { port = 45454; } printf("MY DEST PORT BEFORE AND AFTER\n"); printf("%d, %d\n", port, htons(port)); fflush(stdout); server_addr.sin_family = PF_INET; server_addr.sin_port = htons(port); //server_addr.sin_port = htons(53); server_addr.sin_addr.s_addr = xxx(192,168,1,5); //server_addr.sin_addr.s_addr = xxx(127,0,0,1); //server_addr.sin_addr.s_addr = xxx(74,125,224,72); //server_addr.sin_addr.s_addr = INADDR_LOOPBACK; server_addr.sin_addr.s_addr = htonl(server_addr.sin_addr.s_addr); bzero(&(server_addr.sin_zero), 8); printf("\n UDP Client sending to server at server_addr=%s:%d, netw=%u\n", inet_ntoa(server_addr.sin_addr), ntohs(server_addr.sin_port), server_addr.sin_addr.s_addr); fflush(stdout); if (argc > 2) { client_port = atoi(argv[2]); } else { client_port = 55555; } client_addr.sin_family = PF_INET; client_addr.sin_port = htons(client_port); //client_addr.sin_addr.s_addr = xxx(127,0,0,1); client_addr.sin_addr.s_addr = INADDR_ANY; //client_addr.sin_addr.s_addr = INADDR_LOOPBACK; client_addr.sin_addr.s_addr = htonl(client_addr.sin_addr.s_addr); //bzero(&(client_addr.sin_zero), 8); printf("Binding to client_addr=%s:%d, netw=%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), client_addr.sin_addr.s_addr); fflush(stdout); if (bind(sock, (struct sockaddr *) &client_addr, sizeof(struct sockaddr_in)) == -1) { perror("Bind"); printf("Failure"); exit(1); } printf("Bound to client_addr=%s:%d, netw=%u\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), client_addr.sin_addr.s_addr); fflush(stdout); int nfds = 2; struct pollfd fds[nfds]; fds[0].fd = -1; fds[0].events = POLLIN | POLLERR; //| POLLPRI; fds[1].fd = sock; fds[1].events = POLLIN | 0; //fds[1].events = POLLIN | POLLPRI | POLLOUT | POLLERR | POLLHUP | POLLNVAL | POLLRDNORM | POLLRDBAND | POLLWRNORM | POLLWRBAND; printf("\n fd: sock=%d, events=%x\n", sock, fds[1].events); fflush(stdout); int time = 1000; //pID = fork(); if (pID == 0) { // child -- Capture process send_data[0] = 65; } else if (pID < 0) { // failed to fork printf("Failed to Fork \n"); fflush(stdout); exit(1); } else { //parent send_data[0] = 89; } int ret = 0; struct msghdr recv_msg; int name_len = 64; char name_buf[name_len]; struct iovec iov[1]; int recv_len = 1000; char recv_buf[recv_len]; int control_len = 4000; char control_buf[control_len]; iov[0].iov_len = recv_len; iov[0].iov_base = recv_buf; recv_msg.msg_namelen = name_len; recv_msg.msg_name = name_buf; recv_msg.msg_iovlen = 1; recv_msg.msg_iov = iov; recv_msg.msg_controllen = control_len; recv_msg.msg_control = control_buf; struct cmsghdr *cmsg; int *ttlptr; int received_ttl; struct timeval curr; struct timeval *stamp; if (0) { int len; int i = 0; while (1) { i++; if (1) { printf("(%d) Input msg (q or Q to quit):", i); fflush(stdout); gets(send_data); //len = strlen(send_data); len = 1000; printf("\nlen=%d, str='%s'\n", len, send_data); fflush(stdout); if (len > 0 && len < send_len) { gettimeofday(&curr, 0); numbytes = sendto(sock, send_data, len, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); //sleep(1); ret = poll(fds, nfds, time); if (ret || 0) { if (1) { printf("poll: ret=%d, revents=%x\n", ret, fds[ret].revents); printf( "POLLIN=%x POLLPRI=%x POLLOUT=%x POLLERR=%x POLLHUP=%x POLLNVAL=%x POLLRDNORM=%x POLLRDBAND=%x POLLWRNORM=%x POLLWRBAND=%x\n", (fds[ret].revents & POLLIN) > 0, (fds[ret].revents & POLLPRI) > 0, (fds[ret].revents & POLLOUT) > 0, (fds[ret].revents & POLLERR) > 0, (fds[ret].revents & POLLHUP) > 0, (fds[ret].revents & POLLNVAL) > 0, (fds[ret].revents & POLLRDNORM) > 0, (fds[ret].revents & POLLRDBAND) > 0, (fds[ret].revents & POLLWRNORM) > 0, (fds[ret].revents & POLLWRBAND) > 0); fflush(stdout); } int recv_bytes; if ((fds[ret].revents & (POLLERR)) || 0) { recv_bytes = recvmsg(sock, &recv_msg, MSG_ERRQUEUE); if (recv_bytes > 0) { printf("recv_bytes=%d, msg_controllen=%d\n", recv_bytes, recv_msg.msg_controllen); /* Receive auxiliary data in msgh */ for (cmsg = CMSG_FIRSTHDR(&recv_msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&recv_msg, cmsg)) { printf("cmsg_len=%u, cmsg_level=%u, cmsg_type=%u\n", cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type); if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) { received_ttl = *(int *) CMSG_DATA(cmsg); printf("received_ttl=%d\n", received_ttl); //break; } else if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) { struct sock_extended_err *err = (struct sock_extended_err *) CMSG_DATA(cmsg); printf("ee_errno=%u, ee_origin=%u, ee_type=%u, ee_code=%u, ee_pad=%u, ee_info=%u, ee_data=%u\n", err->ee_errno, err->ee_origin, err->ee_type, err->ee_code, err->ee_pad, err->ee_info, err->ee_data); struct sockaddr_in *offender = (struct sockaddr_in *) SO_EE_OFFENDER(err); printf("family=%u, addr=%s/%u\n", offender->sin_family, inet_ntoa(offender->sin_addr), ntohs(offender->sin_port)); } else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) { struct timeval *stamp = (struct timeval *) CMSG_DATA(cmsg); printf("stamp=%u.%u\n", (uint32_t) stamp->tv_sec, (uint32_t) stamp->tv_usec); printf("diff=%f\n", time_diff(&curr, stamp)); } } if (cmsg == NULL) { /* * Error: IP_TTL not enabled or small buffer * or I/O error. */ } } else { printf("errno=%d\n", errno); perror("recvmsg"); } } else if ((fds[ret].revents & (POLLIN | POLLRDNORM)) || 0) { recv_bytes = recvmsg(sock, &recv_msg, 0); if (recv_bytes > 0) { printf("recv_bytes=%d, msg_controllen=%d\n", recv_bytes, recv_msg.msg_controllen); /* Receive auxiliary data in msgh */ for (cmsg = CMSG_FIRSTHDR(&recv_msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&recv_msg, cmsg)) { printf("cmsg_len=%u, cmsg_level=%u, cmsg_type=%u\n", cmsg->cmsg_len, cmsg->cmsg_level, cmsg->cmsg_type); if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_TTL) { received_ttl = *(int *) CMSG_DATA(cmsg); printf("received_ttl=%d\n", received_ttl); //break; } else if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_TIMESTAMP) { struct timeval *stamp = (struct timeval *) CMSG_DATA(cmsg); } } if (cmsg == NULL) { /* * Error: IP_TTL not enabled or small buffer * or I/O error. */ } } } } } else { printf("Error string len, len=%d\n", len); } } if (0) { if (pID == 0) { numbytes = sendto(sock, send_data, 1, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); printf("\n sent=%d", numbytes); numbytes = sendto(sock, send_data, 1, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); printf("\n sent=%d", numbytes); } else { //numbytes = recvfrom(sock, send_data, 1024, 0, (struct sockaddr *) &client_addr, &addr_len); printf("\n read=%d", numbytes); } fflush(stdout); } if ((strcmp(send_data, "q") == 0) || strcmp(send_data, "Q") == 0) { break; } } } if (1) { struct timeval start, end; int its = 10;//10000; int data_len = 1000; while (data_len < 4000) { gets(send_data); //data_len += 100; //data_len = 1000; int total_bytes = 0; double total_time = 0; int total_success = 0; double diff; int i = 0; while (i < its) { i++; gettimeofday(&start, 0); numbytes = sendto(sock, send_data, data_len, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr)); gettimeofday(&end, 0); diff = time_diff(&start, &end); if (numbytes > 0) { total_success++; total_bytes += numbytes; total_time += diff; } //usleep(100); } //printf("\n diff=%f, len=%d, avg=%f ms, calls=%f, bits=%f", diff, data_len, diff / its, 1000 / (diff / its), 1000 / (diff / its) * data_len); printf("\n len=%d, time=%f, suc=%d, bytes=%d, avg=%f ms, eff=%f, thr=%f, calls=%f, act=%f", data_len, total_time, total_success, total_bytes, total_time / total_success, total_success / (double) its, total_bytes / (double) its / data_len, 1000 / (total_time / total_success), 1000 / (total_time / total_success) * data_len * 8); fflush(stdout); //sleep(5); } } if (0) { int i = 0; int its = 10000; double speed = 15000000; int len = 1000; double time = 8 * len / speed * 1000000; int use = (int) (time + .5);//ceil(time); printf("time=%f, used=%u\n", time, use); fflush(stdout); int *data = (int *) send_data; *(data + 1) = 0; double diff; struct timeval start, end; gettimeofday(&start, 0); while (1) { *data = htonl(i); numbytes = sendto(sock, send_data, len, 0, (struct sockaddr *) &server_addr, sizeof(struct sockaddr_in)); if (numbytes != len) { break; } if (1) { gettimeofday(&end, 0); diff = time_diff(&start, &end) / 1000; printf("time=%f, frames=%d, speed=%f\n", diff, i, 8 * len * i / diff); fflush(stdout); } i++; //usleep(use); } } printf("\n Closing socket"); fflush(stdout); close(sock); printf("\n FIN"); fflush(stdout); while (1) ; return 0; }