示例#1
0
BaseTCPServer::~BaseTCPServer()
{
    // Close socket
    Close();

    // Wait until worker thread terminates
    WaitLoop();
}
示例#2
0
bool BaseTCPServer::Open( uint16 port, char* errbuf )
{
    if( errbuf != NULL )
        errbuf[0] = 0;

    // mutex lock
    MutexLock lock( mMSock );

    if( IsOpen() )
    {
        if( errbuf != NULL )
            snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "Listening socket already open" );
        return false;
    }
    else
    {
        mMSock.Unlock();

        // Wait for thread to terminate
        WaitLoop();

        mMSock.Lock();
    }

    // Setting up TCP port for new TCP connections
    mSock = new Socket( AF_INET, SOCK_STREAM, 0 );

    // Quag: don't think following is good stuff for TCP, good for UDP
    // Mis: SO_REUSEADDR shouldn't be a problem for tcp - allows you to restart
    //      without waiting for conn's in TIME_WAIT to die
    unsigned int reuse_addr = 1;
    mSock->setopt( SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof( reuse_addr ) );

    // Setup internet address information.
    // This is used with the bind() call
    sockaddr_in address;
    memset( &address, 0, sizeof( address ) );

    address.sin_family = AF_INET;
    address.sin_port = htons( port );
    address.sin_addr.s_addr = htonl( INADDR_ANY );

    if( mSock->bind( (sockaddr*)&address, sizeof( address ) ) < 0 )
    {
        if( errbuf != NULL )
            snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "bind(): < 0" );

        SafeDelete( mSock );
        return false;
    }

    unsigned int bufsize = 64 * 1024; // 64kbyte receive buffer, up from default of 8k
    mSock->setopt( SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof( bufsize ) );

#ifdef WIN32
    unsigned long nonblocking = 1;
    mSock->ioctl( FIONBIO, &nonblocking );
#else
    mSock->fcntl( F_SETFL, O_NONBLOCK );
#endif

    if( mSock->listen() == SOCKET_ERROR )
    {
        if( errbuf != NULL )
#ifdef WIN32
            snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "listen() failed, Error: %u", WSAGetLastError() );
#else
            snprintf( errbuf, TCPSRV_ERRBUF_SIZE, "listen() failed, Error: %s", strerror( errno ) );
#endif

        SafeDelete( mSock );
        return false;
    }

    mPort = port;

    // Start processing thread
    StartLoop();

    return true;
}
示例#3
0
文件: aftp.cpp 项目: kotohvost/arvid
int SendFile (char *FileName)
{
  WaitLoop (DelayToTransmit);

  int hFile;
  if ((hFile = open (FileName, O_BINARY | O_RDONLY, FILE_ACCESS)) == -1)
   {
    printf ("-Send file %s not found!\n", FileName);
    return hFile;
   }

  dword FileSize = lseek (hFile, 0, SEEK_END), FileOffset = 0;
  lseek (hFile, 0, SEEK_SET);
  byte *ClusterBuffer = new byte [SizeOrigCluster];

  if (!ClusterBuffer)
    return (int)ClusterBuffer;

  LockMemory (ClusterBuffer, SizeOrigCluster, LOCK_MEMORY);
  // Make file header
  FileHdr *filehdr = (FileHdr*)ClusterBuffer;
  filehdr->FileID  = get_time () + FileSize; // Is static parametr

  dword FileHeaderLen = strlen (FileName) + 1 + sizeof (FileAttr);
  dword FileBlockIndex = 0;

  // Insert empty frames
  vint Semaphore = SizeOrigCluster / SizeDataFrame;
  SendAFrames ((word*)ClusterBuffer, &Semaphore, ID_FRAME, NULL);
  while (Semaphore > 4) {}

  while (FileSize && !StopByUser)
   {
    CheckOnFreeComBuffer ();
    BlockHdr *pBH = (BlockHdr*) ((int)ClusterBuffer + sizeof (FileHdr));
    dword BlockIndex = FileBlockIndex, BlockInCluster = 0;
    dword LastBytes = SizeOrigCluster - sizeof (FileHdr);

    // Divide cluster on blocks
    while (LastBytes)
     {
      if (LastBytes <= sizeof (BlockHdr))
	break;

      BlockInCluster++;
      LastBytes -= sizeof (BlockHdr);

      if (BlockIndex)
       {
	if (LastBytes >= BLOCK_LEN)
	  pBH->Len = BLOCK_LEN;
	else
	  pBH->Len = LastBytes;

	LastBytes -= pBH->Len;
       }
      else
      if (FileHeaderLen <= LastBytes)
       {
	pBH->Len = FileHeaderLen;
	LastBytes -= pBH->Len;
       }
      else
       {
	BlockInCluster--;
	LastBytes = 0;
	break;
       }

      BlockIndex++;
      pBH++;
     }

    // Dinamyc part of file header modify
    filehdr->NumBlock = BlockInCluster;
    filehdr->HdrLen = sizeof (FileHdr) + BlockInCluster * sizeof (BlockHdr);
    byte *pClusterData = (byte*)((int)ClusterBuffer + filehdr->HdrLen);
    pBH = (BlockHdr *) ((int)ClusterBuffer + sizeof (FileHdr));
    dword OffsetToData = filehdr->HdrLen;

    BlockIndex = 0;
    // Skeleton of cluster data fill
    while (BlockInCluster && FileSize)
     {
      BlockIndex++;

      if (!FileBlockIndex)
       {
	FileAttr *pFA = (FileAttr *)pClusterData;
	pFA->Size = FileSize;
	_dos_getfileattr (FileName, &pFA->Attr);
#ifdef __GNUC__
	_dos_getftime (hFile, &pFA->Date, &pFA->Time);
#else
	_dos_getftime (hFile, (word*)&pFA->Date, (word*)&pFA->Time);
#endif
	strcpy ((char*) ((int)pClusterData + sizeof (FileAttr)), FileName);
       }
      else
       {
	read (hFile, pClusterData, pBH->Len);
	pBH->FileOffset = FileOffset;
	FileOffset += pBH->Len;

	if (FileSize >= pBH->Len)
	  FileSize -= pBH->Len;
	else
	 {
	  pBH->Len = FileSize; // truncate block
	  FileSize = 0;
	  // Correct file header
	  filehdr->NumBlock = BlockIndex;
	  filehdr->HdrLen = sizeof (FileHdr) + BlockIndex * sizeof (BlockHdr);
	 }
       }

      pBH->Number = FileBlockIndex++;
      pBH->CRC = GetBlockCRC (pClusterData, pBH->Len);
      pBH->ClusterOffset = OffsetToData;

      OffsetToData += pBH->Len;
      pClusterData += pBH->Len;
      BlockInCluster--;
      pBH++;
     }

    printf ("BlockInCluster %d\n", BlockIndex);
    dword CountCluster;
    while ((CountCluster = SendACluster (1, ClusterBuffer, filehdr->FileID + FileBlockIndex)) != 1) {}
   } // end while FileSize

  delete ClusterBuffer;
  LockMemory (ClusterBuffer, SizeOrigCluster, UNLOCK_MEMORY);
  close (hFile);

  while ((SComFlag || RComFlag || StartFlag) && !StopByUser)
    CheckOnFreeComBuffer ();
  return 1;
}