⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ckcfn2.c

📁 C-Kermit源码。是使用串口/Modem和网络通讯的程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	rcvtimo = (pktintvl + (3L * rttstddev)) / RTT_SCALE + 1;	if (rpackets < 32)		/* Allow for slow start */	  rcvtimo += rcvtimo + 2;	else if (rpackets < 64)	  rcvtimo += rcvtimo / 2 + 1;        /* On a reliable link, don't try too hard to time out. */	/* Especially on fast local network connections. */        if (server && what == W_NOTHING) /* Server command wait */	  rcvtimo = rcvtimo;		/* == srvtim */        else if (reliable == SET_ON && rcvtimo > 0) /* Reliable */	  rcvtimo = rcvtimo +15;	/* and not server command wait */        else                            /* Not reliable or server cmd wait */	  rcvtimo = rcvtimo;	if (rcvtimo < mintime)		/* Lower bound */	  rcvtimo = mintime;	if (maxtime > 0) {		/* User specified an upper bound */	    if (rcvtimo > maxtime)	      rcvtimo = maxtime;	} else if (maxtime == 0) {	/* User didn't specify */	    if (rcvtimo > timint * 6)	      rcvtimo = timint * 6;	}	debug(F101,"RTT rcvtimo","",rcvtimo);    }    return(0);}#endif /* CK_TIMERS *//*  I N P U T  --  Attempt to read packet number 'pktnum'.  *//* This is the function that feeds input to Kermit's finite state machine, in the form of a character in the range 32-126, normally a packet type (uppercase letter) or pseudo-packet-type (lowercase letter). If a special start state is in effect, that state is returned as if it were the type of an incoming packet.*/intinput() {    int type = 0, acktype;		/* Received packet type */    int x, y, k;			/* Workers */    int z, pi, nf;			/* Worker, packet index, NAK flag */    int nak2ack = 0;    debug(F000,"input sstate","",sstate);    debug(F101,"input nakstate","",nakstate);    debug(F000,"input sndtyp","",sndtyp);    debug(F101,"input xitsta","",xitsta);    debug(F101,"input what","",what);    while (1) {				/* Big loop... *//*  It is ttchk()'s responsibility to tell us if the connection is broken,  and to do so instantly and nondestructively -- no blocking, etc, that would  slow down file transfer.*/	if (ttchk() < 0) {	    debug(F100,"input CONNECTION BROKEN","",0);	    fatalio = 1;	    return('q');	}	if (sstate != 0) {		/* If a start state is in effect, */	    type = sstate;		/* return it like a packet type, */	    sstate = 0;			/* and then nullify it. */	    numerrs = 0;		/* (PWP) no errors so far */	    return(type);	}	if (nakstate) {			/* This section for file receiver. */	    if (wslots > 1) {		/* If we're doing windows, */		x = rseqtbl[winlo];	/* see if desired packet already in. */		debug(F101,"input winlo","",winlo);		debug(F101,"input rseqtbl[winlo]","",rseqtbl[winlo]);		if (x > -1) {		/* Already there? */		    if (r_pkt[x].pk_seq == winlo) { /* (double check) */			rsn = winlo;	            /* Yes, return its info */			debug(F101,"input return pre-stashed packet","",rsn);			dumprbuf();			rdatap = r_pkt[x].pk_adr;   /* like rpack would do. */			rln = (int)strlen((char *) rdatap);			type = r_pkt[x].pk_typ;			break;		    }		}	    }	    type = rpack();	        /* Try to read a packet. */	    debug(F101,"input rpack","",type);	    while (type == 'e') {	/* Handle echoes */		debug(F101,"input echo discarded","",type);		type = rpack();	    }#ifdef DEBUG	    if (deblog) {		if (type == 'D')		  debug(F011,"input type D=",(char *)rdatap,39);		else		  debug(F000,"input type",(char *)rdatap,type);	    }#endif /* DEBUG */#ifndef OLDCHKINT	    if (type == 'z') {		epktrcvd = 1;		errpkt((CHAR *)"User cancelled.");		type = 'E';		break;	    }#endif /* OLDCHKINT */	    if (type < -1) {		char * s;		s = (type == -2) ?		  "FAILED - Interrupted" :		    "FAILED - Connection lost";		xxscreen(SCR_PT,'q',0L,s);		debug(F111,"XXX wasclosed",s,wasclosed);#ifdef CKLOGDIAL		dologend();#endif /* CKLOGDIAL */		return('q');		/* Ctrl-C or connection lost */	    }	    if (type < 0) {		/* Receive window full */		/* Another thing to do here would be to delete */		/* the highest packet and NAK winlo.  But that */		/* shouldn't be necessary since the other Kermit */		/* should not have sent a packet outside the window. */		debug(F101,"rpack receive window full","",0);		dumprbuf();		errpkt((CHAR *)"Receive window full.");		type = 'E';		break;	    }	    dumprbuf();#ifdef OLDCHKINT	    if (chkint() < 0) {		/* Check for console interrupts. */		errpkt((CHAR *)"User cancelled."); /* (old way) */		type = 'E';		break;	    }#endif /* OLDCHKINT */#ifdef STREAMING	    if (streaming) {		/* Streaming */		if (type == 'Q' || type == 'T') { /* Errors are fatal. */		    crunched++;		/* For statistics */		    errpkt((CHAR *)"Transmission error on reliable link.");		    type = 'E';		}	    }#endif /* STREAMING */	    if (type == 'E') {		debug(F101,"input got E, nakstate","",nakstate);		break;			/* Error packet */	    }	    if (type == 'Q') {		/* Crunched packet. */		crunched++;		numerrs++;/*  Packet arrived damaged.  It was most likely the packet we were expecting  next, so we send a NAK for that packet.  Prior to 5A(189), we always  NAK'd winlo here, but that was bad because if two (or more) different  packets were damaged, we would keep NAKing the first one and never NAK the  other ones, which could result in a lengthy series of timeouts.  Now we  NAK the oldest as-yet-unNAK'd missing packet.*/#ifdef CK_TIMERS		rcvtimo++;		/* Stretch the timeout a little */#endif /* CK_TIMERS */		z = (winlo + wslots) % 64;  /* Search from winlo to z */		debug(F101,"ZZZ crunched z","",z);		nf = 0;			    /* NAK flag not set yet */		for (x = winlo; x != z; x = (x + 1) % 64) {		    debug(F101,"ZZZ x","",x);		    if (rseqtbl[x] > -1) /* Have I received packet x? */		      continue;		 /* Yes, go on. */		    debug(F101,"ZZZ x not recd yet","",x);		    pi = sseqtbl[x];	 /* No, have I NAK'd it yet? */		    if (pi < 0 || s_pkt[pi].pk_rtr == 0) {			debug(F101,"ZZZ x not NAK'd yet","",x);			nack(x);	 /* No, NAK it now. */			nf = 1;		 /* Flag that I did. */			break;		    }		}		if (!nf) {		/* If we didn't NAK anything above, */		    debug(F101,"ZZZ NAKing winlo","",winlo);		    if (nack(winlo) < 0) { /* we have to NAK winlo (again) */			errpkt((CHAR *)"Too many retries."); /* Too many */			type = 'E';			break;		    }		}		continue;	    }	    if (type == 'T') {		/* Timeout */#ifndef OS2		/* K95 does this its own way */		if (server && srvidl) {		    idletmo = 1;		    debug(F101,"SERVER IDLE TIMEOUT","",srvidl);		    return('q');		}#endif /* OS2 */#ifdef CK_TIMERS		rcvtimo++;		/* Stretch the timeout a little */#endif /* CK_TIMERS */		timeouts++;		debug(F101,"input receive-state timeout, winlo","",winlo);		/* NAK only the packet at window-low */		debug(F101,"input sending NAK for winlo","",winlo);		x = ttchk();		if (x > 0)		/* Don't give up if there is still */		  continue;		/* something to read. */		else if (x < 0) {#ifdef CKLOGDIAL		    dologend();#endif /* CKLOGDIAL */		    fatalio = 1;		    return('q');	/* Connection Lost */		}		if (nack(winlo) < 0) {		    debug(F101,"input sent too many naks","",winlo);		    errpkt((CHAR *)"Too many retries.");		    type = 'E';		    break;		} else continue;	    }	    if (rsn == winlo) {		/* Got the packet we want, done. */#ifdef CK_TIMERS		if (rttflg && timint)	/* Dynamic round trip timers? */		  getrtt(nakstate, rsn); /* yes, do it. */#endif /* CK_TIMERS */		debug(F101,"input rsn=winlo","",rsn);		break;	    }	    /* Got a packet out of order. */	    debug(F101,"input out of sequence, rsn","",rsn);	    k = rseqtbl[rsn];		/* Get window slot of this packet. */	    debug(F101,"input rseqtbl[rsn]","",k);	    if (k < 0) {		debug(F101,"input recv can't find index for rcvd pkt","",rsn);		/* Was "Internal error 21" */		/* This should not happen  */		errpkt((CHAR *)"Sliding windows protocol error.");		type = 'E';		break;	    }	    y = chkwin(rsn,winlo,wslots); /* See what window it's in. */	    debug(F101,"input recv chkwin","",y);	    if (y == 1) {		/* From previous window. */#ifdef STREAMING		if (!streaming)		/* NO RESEND IF STREAMING! */#endif /* STREAMING */		  resend(rsn);		/* Resend the ACK (might have data) */		freerpkt(rsn);		/* Get rid of received packet */		continue;		/* Back to wait for another packet */	    } else {			/* In this window or out of range */		if (y < 0)		/* If out of range entirely, */		  freerpkt(rsn);	/* release its buffer */#ifdef STREAMING		if (streaming) {	/* Streaming (this shouldn't happen) */		    errpkt((CHAR *)"Sequence error on reliable link.");		    type = 'E';		    break;		}#endif /* STREAMING *//* If our receive window is full, NAK window-low */		if (rbufnum < 1) {	/* Receive window full? */		    if (nack(winlo) < 0) {    /* No choice, must NAK winlo. */			errpkt((CHAR *)"Too many retries."); /* Too many */			type = 'E';			break;		    } else continue;		}/*  Receive window not full.  This is a packet in the current window but it is  not the desired packet at winlo.  So therefore there are gaps before this  packet.  So we find the "lowest" unNAK'd missing packet, if any, between  winlo and this one, and NAK it.  If there are no as-yet-unNAK'd missing  packets in the window, then we send nothing and go wait for another packet.  In theory, this could result in a timeout, but in practice it is likely that  the already-NAK'd missing packets are already on their way.  Note, we do not  NAK ahead of ourselves, as that only creates unnecessary retransmissions.*/		for (x = winlo; x != rsn; x = (x + 1) % 64) {		    if (rseqtbl[x] > -1) /* Have I received packet x? */		      continue;		 /* Yes, check next sequence number. */		    pi = sseqtbl[x];	 /* No, have I NAK'd it yet? */		    if (pi < 0 || s_pkt[pi].pk_rtr == 0) {			nack(x);	 /* No, NAK it now. */			break;		    }		}	    }/*!!!*/	} else {			/* Otherwise file sender... */#ifdef STREAMING	    if (streaming && sndtyp == 'D') {		debug(F101,"STREAMING input streaming","",streaming);		debug(F000,"STREAMING input sndtyp","",sndtyp);		rsn = winlo;		type = 'Y';		/* Pretend we got an ACK */	    }#endif /* STREAMING */	    if (!nak2ack) {		/* NAK(n+1) = ACK(n) */		if (wslots > 1) {	/* Packet at winlo already ACK'd? */		    if (sacktbl[winlo]) { /* If so,  */			sacktbl[winlo] = 0; /* Turn off the ACK'd flag */			winlo = (winlo + 1) % 64; /* Rotate the window */			type = 'Y';	/* And return ACK */			debug(F101,			      "input send returning pre-stashed ACK","",			      winlo-1);			break;		    }		}#ifdef STREAMING		if (!(streaming && sndtyp == 'D')) { /* Not streaming | data */		    type = rpack();	/* Try to read an acknowledgement */		} else {		/* Streaming and in Data phase */		    type = 'Y';		/* Assume all is normal */		    if (chkint() < 0)	/* Check for console interrupts. */		      type = 'z';		    else if (ttchk() > 4 + bctu) /* Check for return traffic */		      type = rpack();		    debug(F000,"input streaming type","",type);		}#endif /* STREAMING */		debug(F111,"input send",(char *) rdatap,(int) type);		while (type == 'e') {	/* Handle echoes */		    debug(F000,"echo discarded","",type);		    type = rpack();		}#ifndef OLDCHKINT		if (type == 'z') {		    epktrcvd = 1;		    errpkt((CHAR *)"User cancelled.");		    type = 'E';		    break;		}#endif /* OLDCHKINT */		if (type < -1) {		    xxscreen(SCR_PT,'q',0L,			   ((char *)((type == -2) ?			   "Interrupted" :			   "Connection lost"))			   );#ifdef CKLOGDIAL		    if (type != -2)		      dologend();#endif /* CKLOGDIAL */		    return('q');	/* Ctrl-C or connection lost */		}		if (type == -1) {		    errpkt((CHAR *)"Receive window full"); /* was "internal */		    debug(F101," wslots","",wslots); /* error 18" */		    debug(F101," winlo","",winlo);		    debug(F101," pktnum","",pktnum);		    dumprbuf();		    type = 'E';		    break;		}		dumprbuf();		/* Debugging */#ifdef OLDCHKINT		if (chkint() < 0) {	/* Check for console interrupts. */		    errpkt((CHAR *)"User cancelled.");		    return(type = 'E');		}#endif /* OLDCHKINT */		/* Got a packet */#ifdef STREAMING		if (streaming) {		/* Streaming */		    if (type == 'Q' || type == 'T') { /* Errors are fatal. */			crunched++;	/* For statistics */			errpkt((CHAR *)"Transmission error on reliable link.");			type = 'E';		    }		}#endif /* STREAMING */		if (type == 'E') {		    debug(F101,"input send got E, nakstate","",nakstate);		    break;		/* Error packet */		}		if (type == 'Q') {	/* Crunched packet */		    crunched++;		/* For statistics */		    numerrs++;		/* For packet resizing */		    x = resend(winlo);	/* Resend window-low */		    if (x < 0) {			type = 'E';			errpkt((CHAR *)"Too many retries");			break;		    }		    continue;		}		if (type == 'T') {	/* Timeout waiting for ACKs. */		    timeouts++;		/* Count it */		    numerrs++;		/* Count an error too */		    debug(F101,"input send state timeout, winlo","",winlo);		    /* Retransmit the oldest un-ACK'd packet. */		    debug(F101,"input send resending winlo","",winlo);		    if (resend(winlo) < 0) { /* Check retries */			debug(F101,"input send too many resends","",maxtry);			errpkt((CHAR *)"Too many retries");			return(type = 'E');		    }#ifdef NEWDPL		    /* Reduce prevailing packet length */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -