示例#1
0
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;
}
示例#2
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;
}
示例#3
0
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);
    }
  }

}
示例#4
0
文件: acpica.c 项目: olsner/os
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);
}
示例#5
0
// 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);
  }
}
示例#6
0
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);
}
示例#7
0
文件: mach1.c 项目: aquasync/mach1
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);
}
示例#8
0
文件: server.cpp 项目: mailgyc/cube
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);
	};
}
示例#9
0
文件: vfs.c 项目: thomasloven/os4
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);
}
示例#10
0
/*------------------------------------------------------------------------------*/
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;
  
}
示例#11
0
/*****************************************************************************
* 函 数 名  : 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;
}
示例#12
0
文件: vfs.c 项目: thomasloven/os4
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;
}
示例#13
0
文件: vfs.c 项目: thomasloven/os4
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;
}
示例#14
0
文件: vfs.c 项目: thomasloven/os4
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;
}
示例#15
0
文件: vfs.c 项目: thomasloven/os4
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;
}
示例#16
0
文件: tcp.cpp 项目: adiego73/cvdrone
// --------------------------------------------------------------------------
// 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);
}
示例#17
0
文件: udp.cpp 项目: borceg/cvdrone
// --------------------------------------------------------------------------
// 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);
}
示例#18
0
//-------------------------------------------------------------------
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);
}
示例#19
0
文件: vnode.c 项目: thomasloven/os4
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;
}
示例#20
0
//-------------------------------------------------------------------
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);
}
示例#21
0
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));
  }
}
示例#22
0
文件: duff.c 项目: nitish1402/OPC
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);
}
示例#23
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);
}
示例#24
0
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;
}
示例#25
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;
	}
}