From 0be32705d123d68081852f7c8bf1edd963ebb9a3 Mon Sep 17 00:00:00 2001 From: HappyZ Date: Tue, 27 Sep 2016 02:02:37 -0700 Subject: [PATCH] rewrote server receiver --- .../server_recv_normaltcp/Makefile | 26 +- .../server_recv_normaltcp/main.c | 224 ++++++++++-------- .../server_m_recv_normaltcp | Bin 0 -> 12844 bytes .../server_recv_normaltcp | Bin 0 -> 13811 bytes 4 files changed, 137 insertions(+), 113 deletions(-) create mode 100755 offloading_binaries/server_recv_normaltcp/server_m_recv_normaltcp create mode 100755 offloading_binaries/server_recv_normaltcp/server_recv_normaltcp diff --git a/offloading_binaries/server_recv_normaltcp/Makefile b/offloading_binaries/server_recv_normaltcp/Makefile index 22b2d9c..5d4f287 100644 --- a/offloading_binaries/server_recv_normaltcp/Makefile +++ b/offloading_binaries/server_recv_normaltcp/Makefile @@ -1,22 +1,18 @@ #CC = /media/Lucifer/android/lib/android-18-toolchain/bin/arm-linux-androideabi-gcc -CC = arm-linux-androideabi-gcc -# CC = gcc +CC1 = arm-linux-androideabi-gcc +CC2 = gcc CFLAGS = -pie -fPIE -TARGET = server_recv_normaltcp +TARGET1 = server_m_recv_normaltcp +TARGET2 = server_recv_normaltcp -OBJS = $(patsubst %.c, %.o, $(wildcard *.c)) -HEADERS = $(wildcard *.h) +all: $(TARGET1) $(TARGET2) -all: $(TARGET) +$(TARGET1): main.c + $(CC1) main.c -Wall $(CFLAGS) -o $@ -%.o: %.c $(HEADERS) - $(CC) $(CFLAGS) -c $< -o $@ - -.PRECIOUS: $(TARGET) $(OBJS) - -$(TARGET): $(OBJS) - $(CC) $(OBJS) -Wall $(CFLAGS) -o $@ +$(TARGET2): main.c + $(CC2) main.c -Wall $(CFLAGS) -o $@ clean: - -rm -f *.o - -rm -f $(TARGET) + -rm -f $(TARGET1) + -rm -f $(TARGET2) diff --git a/offloading_binaries/server_recv_normaltcp/main.c b/offloading_binaries/server_recv_normaltcp/main.c index a9ddd13..fdc5a54 100644 --- a/offloading_binaries/server_recv_normaltcp/main.c +++ b/offloading_binaries/server_recv_normaltcp/main.c @@ -1,17 +1,16 @@ /* - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. + * Initial commit by Yibo @ Jul. 28, 2015 + * Last update by Yanzi @ Sept. 26, 2016 */ - -#include -#include + #include #include +#include +#include #include #include #include +#include #include #include #include @@ -19,103 +18,132 @@ #include #include #include +#include +#include #include +#include -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_ALEN 6 /* from */ -#define ETH_P_ALL 0x0003 +#define BUF_SIZ 65536 + +char isNumber(char number[]) +{ + int i = 0; + + //checking for negative numbers + if (number[0] == '-') + i = 1; + for (; number[i] != 0; i++) + { + //if (number[i] > '9' || number[i] < '0') + if (!isdigit(number[i])) + return 0; + } + return 1; +} -#define MY_DEST_MAC0 0xba -#define MY_DEST_MAC1 0xf6 -#define MY_DEST_MAC2 0xb1 -#define MY_DEST_MAC3 0x71 -#define MY_DEST_MAC4 0x09 -#define MY_DEST_MAC5 0x64 - -#define DEFAULT_IF "wlan0" -#define BUF_SIZ 8192 - int main(int argc, char *argv[]) { - int slotLength = 10000; // in microseconds - int quota = 1000000000; // Bytes per slot, default 1GB/slot - int sentInSlot = 0, slot = 1; - double elapsedTime; - - struct iovec iov; - int sockfd, listenfd; - struct ifreq if_idx; - struct ifreq if_mac; - int tx_len = 0; - char sendbuf[BUF_SIZ]; - struct ether_header *eh = (struct ether_header *) sendbuf; - struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header)); - struct sockaddr_ll socket_address; - char ifName[IFNAMSIZ]; - int i, j, ret, sendsize=1488, packet_num=1000000000, offset = 0, port; - int fd; /* file descriptor for file to send */ - struct sockaddr_in servaddr,cliaddr; - socklen_t clilen; - struct timeval t_start,t_end,t_now; - - signal(SIGPIPE, SIG_IGN); - - if (argc > 1) - port = atoi(argv[1]); - else - { - printf("Usage: TCPServer port rate"); - exit(1); + // defaults + uint total_bytes_recv = 0; + // for timing + double elapsedTime; + struct timeval t_start, t_end; + // for socket + int fd = 0; // file descriptor of file to write (receive) + int port; + int recvsize = 4096; + int sockfd, listenfd; // fd + char recvbuf[BUF_SIZ]; + struct sockaddr_in servaddr, cliaddr; + socklen_t clilen; + // for misc + int ret; + unsigned char listenOnce = 0; + + signal(SIGPIPE, SIG_IGN); + + if (argc < 2) + { + printf("Usage: %s <[optional] listenOnce ([0]/1)> <[optional] filepath>\n", argv[0]); + exit(0); } - - if (argc > 2) - packet_num = atoi(argv[2]); - - - listenfd = socket(AF_INET, SOCK_STREAM, 0); - - bzero(&servaddr,sizeof(servaddr)); - servaddr.sin_family = AF_INET; - servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons(port); - bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); - listen(listenfd, 1); - - for(;;) - { - clilen=sizeof(cliaddr); - sockfd = accept(listenfd,(struct sockaddr *)&cliaddr, &clilen); - printf("Accepted.\n"); - //setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); + port = atoi(argv[1]); -// fd = open("/data/local/tmp/bigfile_w", O_WRONLY | O_CREAT | O_TRUNC); - offset = 0; - - if (fd == -1) { - fprintf(stderr, "unable to open the file.\n"); - exit(1); - } - - gettimeofday(&t_start, NULL); - while (offset < packet_num) - { - ret = recv(sockfd, sendbuf, 4096, 0); - if (ret <= 0) - { - printf("recv fail\n"); - usleep(100); - break; - } -// write(fd, sendbuf, ret); - offset += ret; - } - close(sockfd); - gettimeofday(&t_end, NULL); - printf("%lf\n", (t_end.tv_sec-t_start.tv_sec)*1000.0+(t_end.tv_usec-t_start.tv_usec)/1000.0); - } - - close(fd); - - return 0; + if (argc > 2) + listenOnce = 1; + + // listen to socket + listenfd = socket(AF_INET, SOCK_STREAM, 0); + // bind socket and listen + bzero(&servaddr, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(port); + bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); + listen(listenfd, 1); + + // infinity loop to listen + for (;;) + { + clilen = sizeof(cliaddr); + + // wait for one client and accept it once found + sockfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); + printf("Accepted client at %s\n", inet_ntoa(cliaddr.sin_addr)); + + // clear total_bytes_recv to 0 + total_bytes_recv = 0; + + // if instrument to write to a file + if (argc > 3) + { + fd = open(argv[3], O_WRONLY | O_CREAT | O_TRUNC); + if (fd == -1) { + fprintf(stderr, "! Unable to open file %s.\n", argv[2]); + close(sockfd); + if (listenOnce) + break; + continue; // skip and listen to a new one + } + } + + // start timing + gettimeofday(&t_start, NULL); + + // start to receive + for (;;) + { + ret = recv(sockfd, recvbuf, recvsize, 0); + if (ret <= 0) + { + if (errno == 0) + { + if (argc > 3) + close(fd); + break; + } + fprintf(stderr, "! Fail to recv: ret:%d, err:%d; quiting..\n", ret, errno); + exit(1); + } + if (argc > 3) + write(fd, recvbuf, ret); + total_bytes_recv += ret; + // printf("total_bytes_recv %d\n", total_bytes_recv); + } + + // end timing + gettimeofday(&t_end, NULL); + elapsedTime = (t_end.tv_sec - t_start.tv_sec) + (t_end.tv_usec - t_start.tv_usec) / 1000000.0; + printf( + "recv(bytes):%d\nduration(s):%lf\nthroughput(bps):%lf\n", + total_bytes_recv, elapsedTime, total_bytes_recv * 8 / elapsedTime); + + close(sockfd); + + if (listenOnce) + break; + } + + return 0; } diff --git a/offloading_binaries/server_recv_normaltcp/server_m_recv_normaltcp b/offloading_binaries/server_recv_normaltcp/server_m_recv_normaltcp new file mode 100755 index 0000000000000000000000000000000000000000..2b4bf540e68d408c9b2cd64ec33efd5915b3b70a GIT binary patch literal 12844 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 z z_j(2W7HGGB-vjOT?|IPf@%cB<7vTSHv_<_KCpYZ}y&UnKxA|OB-1HYfcY{A*^KYo2 z*MsK#NCHxSZv}l9Xm@->Ks)ON@98Bf=uyy@+|!F@^O5*aA{C15Nrgue(O^_835z8$ zK}Hta5el$U=EFl`1m{6eiPWlaES3$0Q+sCdWICORgroQ2ik)@MFEos*$#^#OKsKDo z;0C6B?asag7z)L5XAp$W zw{63w+c))xdbVxrxhq6&1-TKli@U!6j%}gdP22k+%MPG|>oQ^@cl+o_gyx0hh7d}0 z#%A$YEWz7^79)l}&k~~)`#-tJ=vb4@jYeP&eq)0xX6=eur7+bh9ZaUf`O#D^5gUYz zq-;F?ATC(Oa)YtK&e__7vhQ}Cm{rH>{Alu1)+G$9d}K6vi4~xs6yB4im$`c>f_Nn1 z_0Ui_o5kJDpc@|q;grYXk)v4EHEM^4F1BMmauDGd~a9 zNt9*!2V`txQjX8r%um}ifYe8we}&Am7xnSEo>{kP04c}k?0biW z2r_NpF~fOgz5v`wlw(?j?8x!Vz?{U|>?B9-Hd~JE@NC4)^N^DqIX)LqALV!kV*bPt z0(9hf7R3@ReaN!_@21mkCpmKTHO+xLoN_#S9KDP_6MXuFay;Yk zPW?rj2AK8VTHw@4Io=ySavl5v+(}NmJ_tE-a=#N-FR;K6IVq?-}wr;7jb~DcbMQg=zjp{7Hf_G literal 0 HcmV?d00001 diff --git a/offloading_binaries/server_recv_normaltcp/server_recv_normaltcp b/offloading_binaries/server_recv_normaltcp/server_recv_normaltcp new file mode 100755 index 0000000000000000000000000000000000000000..ab4b1b0705ca3e0119a0bb517ee93913fe411cb1 GIT binary patch literal 13811 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