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

📄 pcattcp.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
            err("setsockopt: sndbuf");
         }

         mes("sndbuf");
      }
      else
      {
         if( setsockopt(
               fd,
               SOL_SOCKET,
               SO_RCVBUF,
               (char * )&sockbufsize,
               sizeof sockbufsize
               ) == SOCKET_ERROR
            )
         {
            err("setsockopt: rcvbuf");
         }

         mes("rcvbuf");
      }
   }
#endif

   //
   // Start TCP Connections
   //
   if( g_Protocol != IPPROTO_UDP )
   {
      if( g_bTransmit )
      {
         //
         // We are the client if transmitting
         //
         if( options )
         {
            if( setsockopt(
                  fd,
                  SOL_SOCKET,
                  options,
                  (PCHAR )&one,
                  sizeof(one)
                  ) == SOCKET_ERROR
               )
            {
               err("setsockopt");
            }
         }

#ifdef TCP_NODELAY
         {
            //
            // Set TCP_NODELAY Send Option
            //
            struct protoent *p;
            int optlen = sizeof( g_nNoDelay );
            p = getprotobyname("tcp");

            if( p && setsockopt(
                        fd,
                        p->p_proto,
                        TCP_NODELAY, 
                        (PCHAR )&g_nNoDelay,
                        sizeof( g_nNoDelay )
                        ) == SOCKET_ERROR
               )
            {
               int nError = WSAGetLastError();
               fprintf( stderr, "  Error: 0x%8.8X\n", nError );
               mes("setsockopt: g_nNoDelay option failed");
            }

            //
            // Query And Display TCP_NODELAY Send Option
            //
            if( p && getsockopt(
                        fd,
                        p->p_proto,
                        TCP_NODELAY, 
                        (PCHAR )&g_nNoDelay,
                        &optlen
                        ) != SOCKET_ERROR
               )
            {
               if( g_nNoDelay )
               {
	               fprintf(stderr,"pcattcp%s: g_nNoDelay ENABLED (%d)\n",
                     g_bTransmit ? "-t" : "-r", g_nNoDelay );
               }
               else
               {
	               fprintf(stderr,"pcattcp%s: g_nNoDelay DISABLED (%d)\n",
                     g_bTransmit ? "-t" : "-r", g_nNoDelay );
               }
            }
            else
            {
               int nError = WSAGetLastError();
               fprintf( stderr, "  Error: 0x%8.8X\n", nError );
               mes("getsockopt: g_nNoDelay option failed");
            }
         }
#endif

         //
         // Connect To Remote Server
         //
         if(connect(fd, (struct sockaddr * )&sinhim, sizeof(sinhim) ) == SOCKET_ERROR)
            err("connect");

         mes("connect");
      }
      else
      {
         //
         // Otherwise, We Are The Server
         //
         listen( fd, 0 );  // allow a queue of 0

         if(options)
         {
            if( setsockopt(
                  fd,
                  SOL_SOCKET,
                  options,
                  (PCHAR )&one,
                  sizeof(one)
                  ) == SOCKET_ERROR
               )
            {
               err("setsockopt");
            }
         }
         
         fromlen = sizeof(frominet);
         domain = AF_INET;

         if( (fd=accept(fd, (struct sockaddr * )&frominet, &fromlen) ) == SOCKET_ERROR)
         {
            err("accept");
         }
         else
         {
            struct sockaddr_in peer;
            int peerlen = sizeof(peer);
            if (getpeername(fd, (struct sockaddr *) &peer, 
				   &peerlen) == SOCKET_ERROR)
            {
               err("getpeername");
            }
            fprintf(stderr,"pcattcp-r: accept from %s\n", 
               inet_ntoa(peer.sin_addr));
         }
      }
   }

   prep_timer();
   errno = 0;

   if( g_bSinkMode )
   {      
      register int cnt;
      if( g_bTransmit )
      {
         KS_FillPattern( buf, g_nBufferSize );

         if( g_Protocol == IPPROTO_UDP )
            Nwrite( fd, buf, UDP_GUARD_BUFFER_LENGTH ); /* rcvr start */

         if( g_bSendContinuously )
         {
            while (Nwrite(fd,buf,g_nBufferSize) == g_nBufferSize)
               nbytes += g_nBufferSize;
         }
         else
         {
            while (g_nNumBuffersToSend-- && Nwrite(fd,buf,g_nBufferSize) == g_nBufferSize)
               nbytes += g_nBufferSize;
         }

         if( g_Protocol == IPPROTO_UDP )
            Nwrite( fd, buf, UDP_GUARD_BUFFER_LENGTH ); /* rcvr end */
      }
      else
      {
         if( g_Protocol == IPPROTO_UDP )
         {
            while( (cnt=Nread(fd,buf,g_nBufferSize)) > 0 )
            {
               static int going = 0;
               if( cnt <= UDP_GUARD_BUFFER_LENGTH )
               {
                  if( going )
                     break;	/* "EOF" */
                  going = 1;
                  prep_timer();
               }
               else
               {
                  nbytes += cnt;
               }
            }
         }
         else
         {
            while( (cnt=Nread(fd,buf,g_nBufferSize) ) > 0)
            {
               nbytes += cnt;
            }
         }
      }
   }
   else
   {
      register int cnt;

      if( g_bTransmit )
      {
         //
         // Read From stdin And Write To Remote
         //
         while( ( cnt = read(0,buf,g_nBufferSize ) ) > 0
            && Nwrite(fd,buf,cnt) == cnt
            )
         {
            nbytes += cnt;
         }
      }
      else
      {
         //
         // Read From Remote And Write To stdout
         //
         while( ( cnt = Nread(fd,buf,g_nBufferSize ) ) > 0
            && write(1,buf,cnt) == cnt
            )
         {
            nbytes += cnt;
         }
      }
   }

	if(errno)
      err("IO");

   tFinish = GetTickCount();

   if( g_Protocol == IPPROTO_UDP && g_bTransmit )
   {
      Nwrite( fd, buf, UDP_GUARD_BUFFER_LENGTH );   // rcvr end
      Nwrite( fd, buf, UDP_GUARD_BUFFER_LENGTH );   // rcvr end
      Nwrite( fd, buf, UDP_GUARD_BUFFER_LENGTH );   // rcvr end
      Nwrite( fd, buf, UDP_GUARD_BUFFER_LENGTH );   // rcvr end
   }

   realt = ((double )tFinish - (double )tStart)/1000;

   fprintf(stdout,
      "pcattcp%s: %.0f bytes in %.2f real seconds = %s/sec +++\n",
      g_bTransmit ? "-t" : "-r",
      nbytes, realt, outfmt(nbytes/realt));

   printf( "numCalls: %d; msec/call: %.2f; calls/sec: %.2f\n",
      numCalls,
      1024.0 * realt/((double )numCalls),
      ((double )numCalls)/realt
      );

   WSACleanup();

   return( 0 );
}

void
err( char *s )
{
	fprintf(stderr,"pcattcp%s: ", g_bTransmit ? "-t" : "-r");
	perror(s);
	fprintf(stderr,"errno=%d\n",errno);
   WSACleanup();
	exit(1);
}

void
mes( char *s )
{
	fprintf(stderr,"pcattcp%s: %s\n", g_bTransmit ? "-t" : "-r", s );
}

// Fill Buffer With Printable Characters...
void KS_FillPattern( char *cp, int cnt )
{
   UCHAR PBPreamble[] = "PCAUSA PCATTCP Pattern";   // 22 Bytes
   register char c;

   c = 0;

   //
   // Insert "PCAUSA Pattern" Preamble
   //
   if( cnt > 22 )
   {
      memcpy( cp, PBPreamble, 22 );
      cp += 22;
      cnt -= 22;
   }

   while( cnt-- > 0 )
   {
      while( !isprint((c&0x7F)) )
      {
         c++;
      }

      *cp++ = (c++&0x7F);
   }
}

/*
 *			N R E A D
 */
int Nread( SOCKET fd, PVOID buf, int count )
{
   struct sockaddr_in from;
   int len = sizeof(from);
   register int cnt;

   if( g_Protocol == IPPROTO_UDP )
   {
		cnt = recvfrom( fd, buf, count, 0, (struct sockaddr * )&from, &len );
		numCalls++;
   }
   else
   {
		if( b_flag )
      {
         cnt = mread( fd, buf, count );	/* fill buf */
      }
      else
      {
         cnt = recv( fd, buf, count, 0 );

         if( cnt == SOCKET_ERROR )
         {
            int nError = WSAGetLastError();
         }

         numCalls++;
      }

		if (touchdata && cnt > 0)
      {
			register int c = cnt, sum;
			register char *b = buf;
         sum = 0;
			while (c--)
				sum += *b++;
		}
	}

	return(cnt);
}

/*
 *			N W R I T E
 */
int Nwrite( SOCKET fd, PVOID buf, int count )
{
   register int cnt;

   if( g_Protocol == IPPROTO_UDP )
   {
again:
      cnt = sendto( fd, buf, count, 0,
               (struct sockaddr * )&sinhim,
               sizeof(sinhim)
               );

      numCalls++;

      if( cnt == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS )
      {
         delay(18000);
         errno = 0;
         goto again;
      }
   }
   else
   {
      cnt = send( fd, buf, count, 0 );
      numCalls++;
   }

   return(cnt);
}

void delay( int us )
{
	struct timeval tv;

	tv.tv_sec = 0;
	tv.tv_usec = us;
	select( 1, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tv );
}

/*
 *			M R E A D
 *
 * This function performs the function of a read(II) but will
 * call read(II) multiple times in order to get the requested
 * number of characters.  This can be necessary because
 * network connections don't deliver data with the same
 * grouping as it is written with.  Written by Robert S. Miles, BRL.
 */
int mread( SOCKET fd, char *bufp, unsigned n)
{
   register unsigned	count = 0;
   register int		nread;

   do
   {
		nread = recv(fd, bufp, n-count, 0);
		numCalls++;
		if(nread < 0)  {
			perror("ttcp_mread");
			return(-1);
		}
		if(nread == 0)
			return((int)count);
		count += (unsigned)nread;
		bufp += nread;
	 } while(count < n);

	return((int)count);
}

#define END(x)	{while(*x) x++;}

void psecs( long l, char *cp )
{
	register int i;

	i = l / 3600;
	if (i) {
		sprintf(cp,"%d:", i);
		END(cp);
		i = l % 3600;
		sprintf(cp,"%d%d", (i/60) / 10, (i/60) % 10);
		END(cp);
	} else {
		i = l;
		sprintf(cp,"%d", i / 60);
		END(cp);
	}
	i %= 60;
	*cp++ = ':';
	sprintf(cp,"%d%d", i / 10, i % 10);
}

void prep_timer( VOID )
{
   tStart = GetTickCount();
}

char *outfmt( double b )
{
   static char obuf[50];

   switch (fmt) {
	case 'G':
	    sprintf(obuf, "%.2f GB", b / 1024.0 / 1024.0 / 1024.0);
	    break;
	default:
	case 'K':
	    sprintf(obuf, "%.2f KB", b / 1024.0);
	    break;
	case 'M':
	    sprintf(obuf, "%.2f MB", b / 1024.0 / 1024.0);
	    break;
	case 'g':
	    sprintf(obuf, "%.2f Gbit", b * 8.0 / 1024.0 / 1024.0 / 1024.0);
	    break;
	case 'k':
	    sprintf(obuf, "%.2f Kbit", b * 8.0 / 1024.0);
	    break;
	case 'm':
	    sprintf(obuf, "%.2f Mbit", b * 8.0 / 1024.0 / 1024.0);
	    break;
    }

    return obuf;
}

⌨️ 快捷键说明

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