int menu(Biobuf *bp, int net) { char *cp; int done; comm->stopped = 1; rawoff(); fprint(2, ">>> "); for(done = 0; !done; ){ cp = Brdline(bp, '\n'); if(cp == 0){ comm->stopped = 0; return -1; } cp[Blinelen(bp)-1] = 0; switch(*cp){ case '!': system(Bfildes(bp), cp+1); done = 1; break; case '.': done = 1; break; case 'q': comm->stopped = 0; return -1; case 'o': switch(*(cp+1)){ case 'd': send3(net, Iac, Do, atoi(cp+2)); break; case 'w': send3(net, Iac, Will, atoi(cp+2)); break; } break; case 'r': comm->returns = !comm->returns; done = 1; break; case 'i': send2(net, Iac, Interrupt); break; case 'b': send2(net, Iac, Break); break; default: fprint(2, STDHELP); break; } if(!done) fprint(2, ">>> "); } rawon(); comm->stopped = 0; return 0; }
/*------------------------------------------------------------------------------*/ u8_t tr1001_send(void) { u8_t *hdr; u16_t hdrlen; u8_t *data; u16_t datalen; int i; hdr = &uip_buf[UIP_LLH_LEN]; hdrlen = UIP_TCPIP_HLEN; data = uip_appdata; if(uip_len < UIP_TCPIP_HLEN) { datalen = 0; } else { datalen = uip_len - UIP_TCPIP_HLEN; } /* Prepare the transmission. */ prepare_transmission(); /* Send first preamble byte. */ send(0xaa); /* Send second preamble byte. */ send(0xaa); /* Send sync byte. */ send(0x0ff); /* Send first start byte. */ send(0x01); /* Send second start byte. */ send(0x07f); /* Send packet header. */ send2(TR1001_TYPE_DATA); send2(++packet_id); send2(uip_len >> 8); send2(uip_len & 0xff); /* Send packet data. */ for(i = 0; i < hdrlen; ++i) { send2(hdr[i]); } for(i = 0;i < datalen; ++i) { send2(data[i]); } /* Send trailing bytes. */ send(0xaa); send(0xaa); /* Turn on reception again. */ rxon(); return UIP_FW_OK; }
void cd_user_md::update_game_info_without_lock(long long uid) { auto user_ptr = get_user(uid); if(user_ptr) { std::string query = "call get_game_info(" + std::to_string(uid) + ")"; auto rs = db_md::get().execute_query(query); while(rs->next()) { auto score = rs->getInt("score"); auto win_count = rs->getInt("win_count"); auto lose_count = rs->getInt("lose_count"); auto ranking = rs->getInt("ranking"); user_ptr->set_score(score); user_ptr->set_win_count(win_count); user_ptr->set_lose_count(lose_count); user_ptr->set_ranking(ranking); json11::Json noti = json11::Json::object { { "type", "update_game_info_noti" }, { "result", true }, { "score", score }, { "win_count", win_count }, { "lose_count", lose_count }, { "ranking", ranking } }; user_ptr->send2(noti); } } }
static void MsgClaimPci(uintptr_t rcpt, uintptr_t addr, uintptr_t pins) { addr &= 0xffff; ACPI_PCI_ID id = { 0, (addr >> 8) & 0xff, (addr >> 3) & 31, addr & 7 }; log(claim_pci, "claim pci %02x:%02x.%x\n", id.Bus, id.Device, id.Function); // Set up whatever stuff to track PCI device drivers in general int irqs[4] = {0}; for (int pin = 0; pin < 4; pin++) { if (!(pins & (1 << pin))) continue; ACPI_STATUS status = RouteIRQ(&id, 0, &irqs[pin]); CHECK_STATUS("RouteIRQ"); log(claim_pci, "%02x:%02x.%x pin %d routed to IRQ %#x\n", id.Bus, id.Device, id.Function, pin, irqs[pin]); } if (pins & ACPI_PCI_CLAIM_MASTER) { u64 value; AcpiOsReadPciConfiguration(&id, PCI_COMMAND, &value, 16); if (!(value & PCI_COMMAND_MASTER)) { value |= PCI_COMMAND_MASTER; AcpiOsWritePciConfiguration(&id, PCI_COMMAND, value, 16); } } pins = (u64)irqs[3] << 48 | (u64)irqs[2] << 32 | irqs[1] << 16 | irqs[0]; send2(MSG_ACPI_CLAIM_PCI, rcpt, addr, pins); hmod(rcpt, (uintptr_t)pci_device_handles + addr, 0); return; failed: send2(MSG_ACPI_CLAIM_PCI, rcpt, 0, 0); } static size_t debugger_buffer_pos = 0; static void debugger_pre_cmd(void) { debugger_buffer_pos = 0; AcpiGbl_MethodExecuting = FALSE; AcpiGbl_StepToNextCall = FALSE; AcpiDbSetOutputDestination(ACPI_DB_CONSOLE_OUTPUT); }
// server side item pickup, acknowledge first client that gets it void pickup(u32 i, int sec, int sender) { if (i>=(u32)sents.size()) return; if (sents[i].spawned) { sents[i].spawned = false; sents[i].spawnsecs = sec; send2(true, sender, SV_ITEMACC, i); } }
void disconnect_client(int n, const char *reason) { printf("client::disconnecting client (%s) [%s]\n", clients[n].hostname.c_str(), reason); enet_peer_disconnect(clients[n].peer); clients[n].type = ST_EMPTY; send2(true, -1, SV_CDIS, n); }
void set_argv(static_context_t *this_context, int argc, char **argv) { array_t *ARGV = array_new(); int i; for (i = 0; i < argc; i++) array_push(this_context, ARGV, string_new_cstr(argv[i])); send2(Object, s_const_set, intern("ARGV"), ARGV); }
void pickup(uint i, int sec, int sender) // server side item pickup, acknowledge first client that gets it { if (i >= (uint) sents.size()) return; if (sents[i].spawned) { sents[i].spawned = false; sents[i].spawnsecs = sec; send2(true, sender, SV_ITEMACC, i); }; }
void chroot(inode_t *node) { CALLOCP(message, vfsm); message->m.msg_type = VFSM_CHRD; memcopy((uint8_t *)&message->chrd.rd, (uint8_t *)node, sizeof(inode_t)); send2(VFS_PID,message); free(waitmsg(VFS_PID,0)); free(message); }
/*------------------------------------------------------------------------------*/ u8_t tr1001_ack(void) { /* Prepare the transmission. */ prepare_transmission(); /* Send first preamble byte. */ send(0xaa); /* Send second preamble byte. */ send(0xaa); /* Send sync byte. */ send(0x0ff); /* Send first start byte. */ send(0x01); /* Send second start byte. */ send(0x07f); /* Send packet header. */ send2(TR1001_TYPE_ACK); send2(((struct tr1001_hdr *)uip_buf)->id); send2(0); send2(0); /* Send trailing bytes. */ send(0xaa); send(0xaa); /* Turn on reception again. */ rxon(); /* beep();*/ return UIP_FW_OK; }
/***************************************************************************** * 函 数 名 : hsUartSend * * 功能描述 : HS UART发送数据接口函数 * * 输入参数 : UINT32 u32SrcAddr 需发送的数据的首地址 * UINT32 u32TransLength 需发送的数据的长度 * * 输出参数 : 无 * 返 回 值 : OK 成功 * ERROR 失败 * * 修改记录 :2010年12月16日 鲁婷 创建 *****************************************************************************/ HSUART_STATUS hsUartSend(UINT8 * pucSrcAddr, UINT32 u32TransLength) { // UINT32 regval; UINT8 * pu8Buffer; UINT32 ulTimes; UINT32 ulLeft; /* 参数的有效性检查 */ if((NULL == pucSrcAddr) || (0 == u32TransLength)) { return HSUART_STATUS_PARA_ERR; } pu8Buffer = pucSrcAddr; ulTimes = u32TransLength / 4; ulLeft = u32TransLength % 4; send4((UINT32*)pu8Buffer, ulTimes); /*lint !e826*/ pu8Buffer = pu8Buffer + ulTimes*4; if(ulLeft == 1) { send1(pu8Buffer, 1); } else if(ulLeft == 2) { send2((UINT16*)pu8Buffer, 1); /*lint !e826*/ } else if(ulLeft == 3) { send2((UINT16*)pu8Buffer, 1); /*lint !e826*/ pu8Buffer = pu8Buffer + 1*2; send1(pu8Buffer, 1); } return HSUART_STATUS_OK; }
stat_t *fstat(uint32_t filp) { CALLOCP(message, vfsm); message->m.msg_type = VFSM_FSTAT; message->fstat.filp = filp; send2(VFS_PID, message); vfsm *reply = (vfsm *)waitmsg(VFS_PID,0); memcopy((uint8_t *)&stat, (uint8_t *)&reply->fstat_reply.node, sizeof(stat_t)); free(message); free(reply); return &stat; }
uint32_t read(uint32_t fp, uint32_t length, char *buffer) { CALLOCP(message, vfsm); message->m.msg_type = VFSM_READ; message->read.filp = fp; message->read.length = length; message->read.buffer = buffer; send2(VFS_PID, message); vfsm *reply = (vfsm *)waitmsg(VFS_PID,0); uint32_t ret = reply->read_reply.length; free(reply); return ret; }
uint32_t open(char *path) { CALLOCP(message, vfsm); message->m.msg_type = VFSM_OPEN; message->open.path_len = strlen(path)+1; message->open.path = path; send2(VFS_PID, message); vfsm *reply = waitmsg(VFS_PID,0); uint32_t ret = reply->open_reply.filp; free(message); free(reply); return ret; }
dirent_t *readdir(inode_t *node, uint32_t offset) { CALLOCP(message, vfsm); message->m.msg_type = VFSM_READDIR; memcopy((uint8_t *)&message->readdir.node, (uint8_t *)node, sizeof(inode_t)); message->readdir.num = offset; send2(VFS_PID, message); vfsm *reply = waitmsg(VFS_PID,0); memcopy((uint8_t *)&dirent, (uint8_t *)&reply->readdir_reply.dirent, sizeof(dirent_t)); free(message); free(reply); return &dirent; }
// -------------------------------------------------------------------------- // TCPSocket::sendf(Messages) // Description : Send the data with format. // Return value : SUCCESS: Number of sent bytes FAILURE: 0 // -------------------------------------------------------------------------- int TCPSocket::sendf(const char *str, ...) { char msg[1024]; // The socket is invalid if (sock == INVALID_SOCKET) return 0; // Apply format va_list arg; va_start(arg, str); vsnprintf(msg, 1024, str, arg); va_end(arg); // Send data return send2(msg, (int)strlen(msg) + 1); }
// -------------------------------------------------------------------------- // UDPSocket::sendf(Messages) // Description : Send the data with format. // Return value : SUCCESS: Number of sent bytes FAILURE: 0 // -------------------------------------------------------------------------- int UDPSocket::sendf(char *str, ...) { char *arg; char msg[1024]; // The socket is invalid if (sock == INVALID_SOCKET) return 0; // Apply format va_start(arg, str); vsprintf_s(msg, sizeof(msg), str, arg); va_end(arg); // Send data return send2(msg, (int)strlen(msg) + 1); }
//------------------------------------------------------------------- void getMinus2Data(IFloat* rcv_buf, IFloat* send_buf, int len, int mu, int nu) { IFloat *tmp_buf = (IFloat *)smalloc(len*sizeof(IFloat)); SCUDirArg send1(send_buf, pos_dir[mu], SCU_SEND, len); SCUDirArg recv1(tmp_buf, neg_dir[mu], SCU_REC, len); SCUTrans(&send1); SCUTrans(&recv1); SCUTransComplete(); SCUDirArg send2(tmp_buf, pos_dir[nu], SCU_SEND, len); SCUDirArg recv2(rcv_buf, neg_dir[nu], SCU_REC, len); SCUTrans(&send2); SCUTrans(&recv2); SCUTransComplete(); sfree(tmp_buf); }
vnode_t *get_vnode(uint32_t driver_num, uint32_t inode_num) { vnode_t *vnode = find_vnode(driver_num, inode_num); if(!vnode) { vnode = get_free_vnode(); vfs_msg_getnode *getnode_msg = (vfs_msg_getnode *)calloc(sizeof(vfs_msg_getnode)); getnode_msg->msg_type = VFSM_GETNODE; getnode_msg->node.driver_num = driver_num; getnode_msg->node.inode_num = inode_num; send2(driver_num, getnode_msg); free(getnode_msg); getnode_msg = waitmsg(driver_num,0); if(getnode_msg->node.driver_num) { memcopy((uint8_t *)vnode, (uint8_t *)&getnode_msg->node, sizeof(vnode_t)); } else { _syscall_printf("\nGetnode failed!",0); } free(getnode_msg); } return vnode; }
//------------------------------------------------------------------- void getMinus3Data(IFloat* rcv_buf, IFloat* send_buf, int len, int dir) { IFloat *tmp_buf = (IFloat *)smalloc(len*sizeof(IFloat)); int i = (dir+1)%4; int j = (dir+2)%4; int k = (dir+3)%4; //-------------------------------------------------------------- // send_buf --> rcv_buf(as a temporary buffer) //-------------------------------------------------------------- SCUDirArg send1(send_buf, pos_dir[i], SCU_SEND, len); SCUDirArg recv1(rcv_buf, neg_dir[i], SCU_REC, len); SCUTrans(&send1); SCUTrans(&recv1); SCUTransComplete(); //-------------------------------------------------------------- // rcv_buf --> tmp_buf //-------------------------------------------------------------- SCUDirArg send2(rcv_buf, pos_dir[j], SCU_SEND, len); SCUDirArg recv2(tmp_buf, neg_dir[j], SCU_REC, len); SCUTrans(&send2); SCUTrans(&recv2); SCUTransComplete(); //-------------------------------------------------------------- // tmp_buf --> rcv_buf //-------------------------------------------------------------- SCUDirArg send3(tmp_buf, pos_dir[k], SCU_SEND, len); SCUDirArg recv3(rcv_buf, neg_dir[k], SCU_REC, len); SCUTrans(&send3); SCUTrans(&recv3); SCUTransComplete(); sfree(tmp_buf); }
void cd_user_md::start_check_alive() { while(is_on_) { auto n = time(NULL); { std::lock_guard<std::mutex> lock(m); for (auto& kv : users_) { auto user = kv.second; //std::cout << kv.first << " has value " << kv.second << std::endl; if(static_cast<time_t>(n - kv.second->get_alive_t()) > WAIT_SEC) { if(server_) { std::cout << "[noti] 킥 당한 유저아이디: " << user->get_uid() << std::endl; std::cout << "킥 유저 시간 간격" << n - kv.second->get_alive_t() << std::endl; server_->send_close(user->connection_, 2); user->destory(); kick_user_without_lock(user->get_uid()); } else { std::cout << "[error] server is nullptr" << std::endl; } } else { std::cout << "[debug] 연결중 uid: " << user->get_uid() << std::endl; std::cout << "커넥션 유저 시간 간격" << n - kv.second->get_alive_t() << std::endl; json11::Json res = json11::Json::object { { "type", "update_alive_noti" }, }; user->send2(res); } } } //std::cout << "[debug] wait for 30 sec" << std::endl; std::this_thread::sleep_for(std::chrono::seconds(2)); } }
int main (int argc, char **argv) { char *from, *to; int i; struct timeval before, after; from = (char *) malloc(BUFLEN * sizeof(char)); to = (char *) malloc(BUFLEN * sizeof(char)); memset(from, 'a', (BUFLEN * sizeof(char))); printf("array init done\n"); printf("calling send\n"); gettimeofday(&before, NULL); send(to, from, BUFLEN); gettimeofday(&after, NULL); printf("secs=%lf\n", after.tv_sec - before.tv_sec); printf("calling send2\n"); gettimeofday(&before, NULL); send2(to, from, BUFLEN); gettimeofday(&after, NULL); printf("secs=%lf\n", after.tv_sec - before.tv_sec); if (strcmp(from,to) == 0) { printf("from=to\n"); } else { printf("from!=to\n"); } free(from); free(to); return(0); }
// server side processing of updates: does very little and most state is tracked // client only could be extended to move more gameplay to server (at expense of // lag) void process(ENetPacket * packet, int sender) { // sender may be -1 const u16 len = *(u16*) packet->data; if (ENET_NET_TO_HOST_16(len)!=packet->dataLength) { disconnect_client(sender, "packet length"); return; } u8 *end = packet->data+packet->dataLength; u8 *p = packet->data+2; char text[MAXTRANS]; int cn = -1, type; while (p<end) switch (type = getint(p)) { case SV_TEXT: sgetstr(); break; case SV_INITC2S: sgetstr(); strcpy_s(clients[cn].name, text); sgetstr(); getint(p); break; case SV_MAPCHANGE: { sgetstr(); int reqmode = getint(p); if (reqmode<0) reqmode = 0; if (smapname[0] && !mapreload && !vote(text, reqmode, sender)) return; mapreload = false; mode = reqmode; minremain = mode&1 ? 15 : 10; mapend = lastsec+minremain*60; interm = 0; strcpy_s(smapname, text); resetitems(); sender = -1; } break; case SV_ITEMLIST: { int n; while ((n = getint(p))!=-1) if (notgotitems) { server_entity se = { false, 0 }; while (sents.size()<=n) sents.push_back(se); sents[n].spawned = true; } notgotitems = false; } break; case SV_ITEMPICKUP: { const int n = getint(p); pickup(n, getint(p), sender); } break; case SV_PING: send2(false, cn, SV_PONG, getint(p)); break; case SV_POS: { cn = getint(p); if (cn<0 || cn>=clients.size() || clients[cn].type==ST_EMPTY) { disconnect_client(sender, "client num"); return; } int size = msgsizelookup(type); assert(size!=-1); loopi(size-2) getint(p); } break; case SV_SENDMAP: { sgetstr(); const auto mapsize = getint(p); sendmaps(sender, text, mapsize, p); } return; case SV_RECVMAP: send(sender, recvmap(sender)); return; case SV_EXT: // allows for new features that require no server updates for (int n = getint(p); n; n--) getint(p); break; default: { const int size = msgsizelookup(type); if (size==-1) { disconnect_client(sender, "tag type"); return; }; loopi(size-1) getint(p); } } if (p>end) { disconnect_client(sender, "end of packet"); return; }; multicast(packet, sender); }
int main(int argc, char *argv[]) { int sockfd; struct addrinfo hints, *servinfo, *p; int rv; int numbytes; struct sockaddr_storage their_addr; char buf[MAXBUFLEN+HEADERSIZE]; socklen_t addr_len; char s[INET6_ADDRSTRLEN]; int cwnd; double pl, pc; // extract argument parameters if (argc != 5) { fprintf(stderr,"usage: receiver <portnumber> <CWnd> <Pl> <Pc>\n"); exit(1); } char *port = argv[1]; cwnd = atoi(argv[2]); pl = atof(argv[3]); pc = atof(argv[4]); if(pl < 0 || pc < 0 || pl > 1 || pc > 1) { fprintf(stderr,"Pl and Pc must be between 0 and 1!\n"); exit(1); } memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // set to AF_INET to force IPv4 hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, port, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { perror("sender: socket"); continue; } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("sender: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "Error: sender failed to bind socket\n"); return 2; } freeaddrinfo(servinfo); printf("Waiting for requested filename...\n"); addr_len = sizeof their_addr; if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0, (struct sockaddr *)&their_addr, &addr_len)) == -1) { printf("Error: failed to receive filename\n"); exit(1); } printf("Received filename from %s\n", inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof s)); buf[numbytes] = '\0'; printf("Requested filename: \"%s\"\n", buf); // buf contains requested file name; if it exists, send back packets (up to 1 KB at a time) to receiver // create source buffer to fopen and fread designated file char *source = NULL; char sourcePacket[MAXBUFLEN+HEADERSIZE]; FILE *fp = fopen(buf, "r"); size_t sourceLength; if (fp==NULL) { // send any packet with seq=0 and fin=1 to represent no file found send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0); printf("Error: file not found!\n"); exit(1); } if (fseek(fp, 0L, SEEK_END) == 0) { // set fsize to file size long fsize = ftell(fp); if (fsize == -1) { // send any packet with seq=0 and fin=1 to represent no file found send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0); printf("Error: file size error!\n"); exit(1); } // allocate source buffer to filesize source = malloc(sizeof(char) * (fsize + 1)); // return to front of file if (fseek(fp, 0L, SEEK_SET) != 0) { // send any packet with seq=0 and fin=1 to represent no file found send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0); free(source); printf("Error: file size error!\n"); exit(1); } // set source to file data sourceLength = fread(source, sizeof(char), fsize, fp); // check file source for fread errors if (sourceLength == 0) { // send any packet with seq=0 and fin=1 to represent no file found send2(sockfd, buf, strlen(buf), (struct sockaddr *)&their_addr, addr_len, 0, 0, 1, 0, 0, 0); free(source); printf("Error: file reading error!\n"); exit(1); } // NULL-terminate the source source[sourceLength] = '\0'; } // close file fclose(fp); // initialize variables for sending/receiving acks int seq=0; int ack=0; size_t len=0; short fin=0; short crc=0; int expectedAck=0; int windowPosition=0; int tempPosition=0; while(fin!=1) { int numPacketsSent = 0; tempPosition = windowPosition; // check that more packets need to be sent and we have not exceeded our send window while(tempPosition<sourceLength && numPacketsSent<cwnd) { // determine size (since it may be less than MAXBUFLEN if last packet to be sent) int size = MAXBUFLEN; if(sourceLength-tempPosition<MAXBUFLEN) size = sourceLength-tempPosition; // create temp array holding data to be sent char temp[MAXBUFLEN]; bzero(temp, MAXBUFLEN); memcpy(temp, source+tempPosition, size); // send packet with headers and data numbytes = send2(sockfd, temp, size, (struct sockaddr *)&their_addr, addr_len, tempPosition, seq+len, (tempPosition+MAXBUFLEN>=sourceLength), 0, pl, pc); //printf("Sent packet of %d-bytes\n", size); if (numbytes == -1) { printf("Packet with sequence #%d lost!\n", tempPosition); } else if(numbytes == -2) { printf("Packet with sequence #%d corrupted!\n", tempPosition); } else printf("Sent %d bytes with sequence #%d\n", numbytes, tempPosition); // increment position of data to send tempPosition+=MAXBUFLEN; // increment number of packets sent this round numPacketsSent++; } int numAcksReceived=0; // check that acks of packets sent have been received while(numAcksReceived < numPacketsSent) { // initialize variables fd_set inSet; struct timeval timeout; int received; FD_ZERO(&inSet); FD_SET(sockfd, &inSet); // wait for specified time timeout.tv_sec = WAITS; timeout.tv_usec = WAITU; // check for acks received = select(sockfd+1, &inSet, NULL, NULL, &timeout); // if timeout and no acks were received, break and maintain window position if(received < 1) { printf("Timed out while waiting for ACK!\n"); break; } // otherwise, fetch the ack numbytes = receive2(sockfd, buf, &len, (struct sockaddr *)&their_addr, &addr_len, &seq, &ack, &fin, &crc); //printf("got ack with: %d/%d/%d/%d (s/a/f/c)\n", seq, ack, fin, crc); if(fin == 1) { printf("ACK #%d received!\n", ack); // FIN rides on the back of the last data packet printf("FIN sent!\n"); // FINACK is guaranteed to arrive; packet loss/corruption disabled printf("FINACK received!\n"); break; } // ignore ack if it's corrupted (we define this as crc == 1); break and maintain window position if(crc == 1) { printf("ACK #%d is corrupted! Ignoring it.\n", ack); break; } // ack is the one we were expecting, so we can increment windowPosition and expect the next ack // true if ack is at most expectedAck and more than expectedAck-MAXBUFLEN if(ack > expectedAck && ack <= expectedAck + MAXBUFLEN) { printf("ACK #%d received!\n", ack); numAcksReceived++; expectedAck += MAXBUFLEN; // expect the next ack (assume it's a MAXBUFLEN-byte packet) windowPosition += MAXBUFLEN; } } // at this point, if we didn't receive the expected ACK, continue } printf("File finished transmitting! Sender terminating...\n"); // free file source and close socket free(source); close(sockfd); return 0; }
/* * Read from the network and write to the screen. If 'stopped' is set * spin and don't read. Filter out spurious carriage returns. */ void fromnet(int net) { int c; int crnls = 0, freenl = 0, eofs; Biobuf ib, ob; Binit(&ib, net, OREAD); Binit(&ob, 1, OWRITE); eofs = 0; for(;;){ if(Bbuffered(&ib) == 0) Bflush(&ob); if(interrupted){ interrupted = 0; send2(net, Iac, Interrupt); } c = Bgetc(&ib); if(c < 0){ if(eofs++ >= 2) return; continue; } eofs = 0; switch(c){ case '\n': /* skip nl after string of cr's */ if(!opt[Binary].local && !comm->returns){ ++crnls; if(freenl == 0) break; freenl = 0; continue; } break; case '\r': /* first cr becomes nl, remainder dropped */ if(!opt[Binary].local && !comm->returns){ if(crnls++ == 0){ freenl = 1; c = '\n'; break; } continue; } break; case 0: /* remove nulls from crnl string */ if(crnls) continue; break; case Iac: crnls = 0; freenl = 0; c = Bgetc(&ib); if(c == Iac) break; if(Bflush(&ob) < 0) return; if(control(&ib, c) < 0) return; continue; default: crnls = 0; freenl = 0; break; } if(Bputc(&ob, c) < 0) return; } }