Sunteți pe pagina 1din 4

#include #include #include #include #include #include #include #include #include #include #define #define #define #define #define

#define

<stdlib.h> <stdio.h> <sys/types.h> <sys/socket.h> <netinet/in.h> <string.h> <unistd.h> <errno.h> <linux/tcp.h> <unistd.h> BUF_SIZE 24*1024 /*max text line length*/ SERV_PORT 3000 /*port*/ LISTENQ 8 /*maximum number of client connections */ RCVBUF_MAX (512*1024) RCVBUF_MIN (32*1024) MAX_WRITE_DATA (700*1024)

void get_bufs(int fd, const char* prefix) { int rcvBuf=0, sndBuf=0, wndClamp=0; socklen_t rcvBufLen = sizeof rcvBuf; socklen_t sndBufLen = sizeof sndBuf; socklen_t wndClampLen = sizeof wndClamp; if(getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvBuf, &rcvBufLen) == -1) { printf( "Error getting SO_RCVBUF: %s\n", strerror(errno)); } if(getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndBuf, &sndBufLen) == -1) { printf( "Error getting SO_SNDBUF: %s\n", strerror(errno)); } if(getsockopt(fd, IPPROTO_TCP, TCP_WINDOW_CLAMP, &wndClamp, &wndClampLen ) == -1) { printf( "Error getting TCP_WINDOW_CLAMP: %s\n", strerror(errno)) ; } printf("%s:\t Get =>\t SO_RCVBUF = %d,\t SO_SNDBUF = %d,\t TCP_WINDOW_CL AMP = %d\n",prefix, rcvBuf, sndBuf, wndClamp); } void set_bufs(int fd, const char* prefix, int rcvBuf, int sndBuf, int wndClamp) { printf("%s:\t Set =>\t SO_RCVBUF = %d,\t SO_SNDBUF = %d,\t TCP_WINDOW_CL AMP = %d\n",prefix, rcvBuf, sndBuf, wndClamp); if (rcvBuf > 0) { if(setsockopt(fd, SOL_SOCKET, SO_RCVBUF,&rcvBuf,sizeof(rcvBuf)) == -1){ printf( "Error setting SO_RCVBUF: %s\n", strerror(errno) ); } } if (wndClamp > 0) { if(setsockopt(fd, IPPROTO_TCP, TCP_WINDOW_CLAMP,&wndClamp,sizeof (wndClamp)) == -1){ printf( "Error setting TCP_WINDOW_CLAMPs: %s\n", strerro

r(errno)); } } if (sndBuf > 0) { if(setsockopt(fd, SOL_SOCKET, SO_SNDBUF,&sndBuf,sizeof(sndBuf)) == -1){ printf( "Error setting SO_SNDBUF: %s\n", strerror(errno) ); } } } int handlePOST(int connfd, int late_rcv_buf, int late_snd_buf, int late_wnd_clam p, int sleep_point) { int n=0, bytesRead=0; char buf[BUF_SIZE]; printf("\nHandling POST\n"); set_bufs(connfd, "After accept", late_rcv_buf, late_snd_buf, late_wnd_cl amp); get_bufs(connfd, "After accept"); while ( (n = read(connfd, buf, BUF_SIZE)) > 0) { bytesRead += n; if ((sleep_point > 0) && (bytesRead >= sleep_point)){ printf("Sleeping 1 sec, bytes = %d\n", bytesRead); sleep(1); } } return n; } int handleGET(int connfd, int late_rcv_buf, int late_snd_buf, int late_wnd_clamp ) { int n=0, bytesWritten=0, iter=0; const char respHdr[] = "HTTP/1.1 200 OK\nContent-Type: application/octet -stream\nConnection: close\n\n"; char buf[BUF_SIZE]; bzero(buf, BUF_SIZE); printf("\nHandling GET\n"); set_bufs(connfd, "After accept", late_rcv_buf, late_snd_buf, late_wnd_cl amp); get_bufs(connfd, "After accept"); if ((n = write(connfd, respHdr, strlen(respHdr))) > 0) { while ( (n = write(connfd, buf, BUF_SIZE)) > 0) { bytesWritten += n; iter++; if (bytesWritten >= MAX_WRITE_DATA){ break;

} } } printf("%d bytes written in %d write calls (%d bytes/write)\n", bytesWri tten, iter, (int)(bytesWritten/iter)); return n; } int main (int argc, char **argv) { int listenfd, connfd, n, bytesRead = 0; /*set the max limit on the recieve buffer*/ int rcvbuf_max = RCVBUF_MAX; int rcvbuf_min = RCVBUF_MIN; int init_rcv_buf=-1, init_snd_buf=-1, init_wnd_clamp=-1, late_rcv_buf=-1 , late_snd_buf=-1, late_wnd_clamp=-1, sleep_point=-1; int iter = 0; socklen_t clilen; socklen_t optlen; int rcvbuf=0; char buf[BUF_SIZE]; struct sockaddr_in cliaddr, servaddr; optlen = sizeof rcvbuf; if (argc != 8){ printf( "Usage: %s <init_rcv_buf> <init_snd_buf> <init_wnd_clamp > <late_rcv_buf> <late_snd_buf> <late_wnd_clamp> <bytes_to_read_before_sleep>\n" , argv[0]); return 0; } init_rcv_buf = (int)strtol(argv[1], NULL, 10); init_snd_buf = (int)strtol(argv[2], NULL, 10); init_wnd_clamp = (int)strtol(argv[3], NULL, 10); late_rcv_buf = (int)strtol(argv[4], NULL, 10); late_snd_buf = (int)strtol(argv[5], NULL, 10); late_wnd_clamp = (int)strtol(argv[6], NULL, 10); sleep_point = (int)strtol(argv[7], NULL, 10); printf( "Startup: init_rcv_buf=%d, init_snd_buf=%d, init_wnd_clamp=%d, l ate_rcv_buf=%d, late_snd_buf=%d, late_wnd_clamp=%d sleep_point=%d\n", init_rcv_buf, init_snd_buf, init_wnd_clamp, late_ rcv_buf, late_snd_buf, late_wnd_clamp, sleep_point); //creation of the socket listenfd = socket(AF_INET, SOCK_STREAM, 0); if(listenfd < 0) { perror("Socket Error"); exit(1); } //preparation of the socket address servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_PORT);

if(bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0){ perror("Bind Error"); exit(1); } get_bufs(listenfd, "Initial buff."); set_bufs(listenfd, "Before accept", init_rcv_buf, init_snd_buf, init_wnd _clamp); get_bufs(listenfd, "Before accept"); if(listen(listenfd, LISTENQ) < 0) { perror("Listen Error"); exit(1); } printf("\nServer running...waiting for connections.\n"); for ( ; ; ) { clilen = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen) ; if(connfd < 0 ) { perror("Bind Error"); exit(1); } // Read the request headers if ((n = read(connfd, buf, 2048)) > 0) { // Handle the payload if ((n > 3) && !memcmp(buf, "GET", 3)){ n = handleGET(connfd, late_rcv_buf, late_snd_buf , late_wnd_clamp); } else { n = handlePOST(connfd, late_rcv_buf, late_snd_bu f, late_wnd_clamp, sleep_point); } } if (n < 0) { perror("Read error"); exit(1); } printf("Connection closed\n"); close(connfd); } //close listening socket close(listenfd); }

S-ar putea să vă placă și