int main(int argc,char* argv[]) { int s1,port,i,n,r,Sb,Sn,Rn,flag=0,w=5,EarliestMiss=-1; char buff[256]; if(argc<2) { printf("Port? : "); scanf("%d",&port); gets(buff); } else port=atoi(argv[1]); s1=connectto("127.0.0.1",port); printf("Enter the total number of packets to be sent : "); scanf("%d",&n); printf("Enter the percentage packet lose rate : "); scanf("%d",&r); printf("Selective repeat with window size %d\n",w); Sb=0; Sn=w-1; while(1) { for(i=Sb; i<=Sn; i++) { if(i<n) sendpacket(s1,i,r); if(waittoread(s1)==1) { bzero(&buff,256); read(s1,buff,255); printf("Request for packet %s received \n",buff); Rn=atoi(buff); if(Rn>EarliestMiss) EarliestMiss=Rn; } } while(EarliestMiss>=Sb && EarliestMiss<=sn) { sendpacket(s1,EarliestMiss,r); if(waittoread(s1)==1) { bzero(&buff,256); read(s1,buff,255); printf("Request for packet %s received\n",buff); Rn=atoi(buff); EarliestMiss=Rn; } } Sn=Sn+w; Sb=Sb+w; if(Sb>=n) break; printf("Moving window forward\n"); } close(s1); printf("Client closed \n"); }
ssize_t atm_recv(ATM *atm, char *data, size_t max_data_len) { // Returns the number of bytes received; negative on error if (waittoread(atm->sockfd, 2)) return recvfrom(atm->sockfd, data, max_data_len, 0, NULL, NULL); else return -1; }
// main socket server static void *server(void *asock){ putlog("server(): getpid: %d, pthread_self: %lu, tid: %lu",getpid(), pthread_self(), syscall(SYS_gettid)); int sock = *((int*)asock); if(listen(sock, BACKLOG) == -1){ putlog("listen() failed"); WARN("listen"); return NULL; } while(1){ socklen_t size = sizeof(struct sockaddr_in); struct sockaddr_in their_addr; int newsock; if(!waittoread(sock)) continue; newsock = accept(sock, (struct sockaddr*)&their_addr, &size); if(newsock <= 0){ putlog("accept() failed"); WARN("accept()"); continue; } struct sockaddr_in* pV4Addr = (struct sockaddr_in*)&their_addr; struct in_addr ipAddr = pV4Addr->sin_addr; char str[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &ipAddr, str, INET_ADDRSTRLEN); putlog("Got connection from %s", str); DBG("Got connection from %s\n", str); pthread_t handler_thread; if(pthread_create(&handler_thread, NULL, handle_socket, (void*) &newsock)){ putlog("server(): pthread_create() failed"); WARN("pthread_create()"); }else{ DBG("Thread created, detouch"); pthread_detach(handler_thread); // don't care about thread state } } putlog("server(): UNREACHABLE CODE REACHED!"); }
static void *handle_socket(void *asock){ FNAME(); int sock = *((int*)asock); int webquery = 0; // whether query is web or regular char buff[BUFLEN]; ssize_t rd; double t0 = dtime(); while(dtime() - t0 < SOCKET_TIMEOUT){ if(!waittoread(sock)){ // no data incoming continue; } if(!(rd = read(sock, buff, BUFLEN-1))){ break; } DBG("Got %zd bytes", rd); if(rd < 0){ // error DBG("Nothing to read from fd %d (ret: %zd)", sock, rd); break; } // add trailing zero to be on the safe side buff[rd] = 0; // now we should check what do user want char *got, *found = buff; if((got = stringscan(buff, "GET")) || (got = stringscan(buff, "POST"))){ // web query webquery = 1; char *slash = strchr(got, '/'); if(slash) found = slash + 1; // web query have format GET /some.resource } // here we can process user data DBG("user send: %s\nfound=%s", buff, found); if(GP->echo){ if(!send_data(sock, webquery, found)){ putlog("can't send data, some error occured"); } } pthread_mutex_lock(&mutex); const char *proto = "Commands: open, close, status"; if(strstr(found, "open")){ DBG("User asks 2 open"); putlog("User asks to open"); cmd = CMD_OPEN; send_data(sock, webquery, "OK\n"); }else if(strstr(found, "close")){ DBG("User asks 2 close"); putlog("User asks to close"); cmd = CMD_CLOSE; send_data(sock, webquery, "OK\n"); }else if(strstr(found, "weather")){ send_data(sock, webquery, weather); }else if(strstr(found, "status")){ DBG("User asks 4 status"); send_data(sock, webquery, status); }else send_data(sock, webquery, proto); pthread_mutex_unlock(&mutex); break; } close(sock); pthread_exit(NULL); return NULL; }