BaseTCPServer::~BaseTCPServer() { // Close socket Close(); // Wait until worker thread terminates WaitLoop(); }
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; }
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; }