Пример #1
0
void UDPSocket::open(unsigned short localPort)
{
	// create
	mSocketFD = socket(AF_INET,SOCK_DGRAM,0);
	if (mSocketFD<0) {
		perror("socket() failed");
		throw SocketError();
	}
	// Set "close on exec" flag to avoid open sockets inheritance by
	// child processes, like 'transceiver'.
	int flags = fcntl(mSocketFD, F_GETFD);
	if (flags >= 0) fcntl(mSocketFD, F_SETFD, flags | FD_CLOEXEC);


	// bind
	struct sockaddr_in address;
	size_t length = sizeof(address);
	bzero(&address,length);
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = INADDR_ANY;
	address.sin_port = htons(localPort);
	if (bind(mSocketFD,(struct sockaddr*)&address,length)<0) {
		perror("bind() failed");
		throw SocketError();
	}
}
Пример #2
0
void UDDSocket::open(const char* localPath)
{
	// create
	mSocketFD = socket(AF_UNIX,SOCK_DGRAM,0);
	if (mSocketFD<0) {
		perror("socket() failed");
		devassert(0);
		throw SocketError();
	}

	// bind
	struct sockaddr_un address;
	size_t length = sizeof(address);
	bzero(&address,length);
	address.sun_family = AF_UNIX;
	strcpy(address.sun_path,localPath);
	unlink(localPath);
	if (bind(mSocketFD,(struct sockaddr*)&address,length)<0) {
		char buf[1100];
		sprintf(buf,"bind(path %s) failed",localPath);
		perror(buf);
		devassert(0);
		throw SocketError();
	}
}
Пример #3
0
Future<Nothing> connect(const Socket& socket, const Address& to)
{
  // Now check that a successful connection was made.
  int opt;
  socklen_t optlen = sizeof(opt);
  int s = socket.get();

  // NOTE: We cast to `char*` here because the function prototypes on Windows
  // use `char*` instead of `void*`.
  if (::getsockopt(
          s,
          SOL_SOCKET,
          SO_ERROR,
          reinterpret_cast<char*>(&opt),
          &optlen) < 0) {
    return Failure(
        SocketError("Failed to get status of connection to " + stringify(to)));
  }

  if (opt != 0) {
    // Make the error visible to the `SocketError` constructor by pushing
    // it into the global per-thread error. MESOS-6520 which should
    // allow us to pass the error code directly into `SocketError`.

#ifdef __WINDOWS__
    ::WSASetLastError(opt);
#else
    errno = opt;
#endif

    return Failure(SocketError("Failed to connect to " + stringify(to)));
  }

  return Nothing();
}
Пример #4
0
ClientSocket::ClientSocket(const std::string & hostNameOrIpAddress, const HostShort & portNumber)
{
    // Should have been initialized by the superclass.
    assert(socketId != NET_INVALID_SOCKET_ID);

    // Must have an IP address or URL.
    assert(!hostNameOrIpAddress.empty());

    //
    // Note: `gethostbyname()` is deprecated in WinSock2 in favor
    // of `getaddrinfo()`. So this is a possible future improvement.
    //
    hostent * hostEntity = gethostbyname(hostNameOrIpAddress.c_str());
    if (hostEntity == nullptr)
    {
        Close();
        throw SocketError("Failed to get hostent for " + hostNameOrIpAddress);
    }

    sockaddr_in addr;
    std::memset(&addr, 0, sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_port   = portNumber.ToNetShort().GetRawValue();
    addr.sin_addr   = *reinterpret_cast<in_addr *>(hostEntity->h_addr);

    if (connect(socketId, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)) != 0)
    {
        Close();
        throw SocketError("Failed to connect with host " + hostNameOrIpAddress +
                " at port #" + std::to_string(portNumber.GetRawValue()));
    }
}
Пример #5
0
    void Socket::setBlockingMode(bool isBlocking) {
#ifndef _WIN32
        DB(PrintStatus(fd));
        if (!_myIsConnected) {
            AC_WARNING << "Socket::setBlockingMode setting blocking mode of a not connected socket, the mode will be lost after you connect";
        }
        int status = fcntl(fd, F_GETFL, 0);
        if (!isBlocking) {
            status |= O_NONBLOCK;
        } else {
            status &= ~O_NONBLOCK;
        }
        if (fcntl(fd, F_SETFL, status)== -1) {
            throw SocketError(getLastSocketError(), "Socket::setBlockingMode failed");
        }
#else
        u_long theFlag = 1;
        if (isBlocking) {
            theFlag = 0;
        }
        int theRC = ioctlsocket(fd, FIONBIO, &theFlag);
        if (theRC == SOCKET_ERROR) {
            int err = getLastSocketError();
            throw SocketError(err, "Socket::setBlockingMode failed");
        }
#endif
    }
Пример #6
0
std::vector<SocketStatus> Kqueue::wait(const SocketTable &table, int ms)
{
	std::vector<SocketStatus> sockets;
	timespec ts = { 0, 0 };
	timespec *pts = (ms <= 0) ? nullptr : &ts;

	ts.tv_sec = ms / 1000;
	ts.tv_nsec = (ms % 1000) * 1000000;

	int nevents = kevent(m_handle, nullptr, 0, &m_result[0], m_result.capacity(), pts);

	if (nevents == 0) {
		throw SocketError(SocketError::Timeout, "kevent");
	}
	if (nevents < 0) {
		throw SocketError(SocketError::System, "kevent");
	}

	for (int i = 0; i < nevents; ++i) {
		SocketAbstract *sc = table.at(m_result[i].ident).first;
		int flags = m_result[i].filter == EVFILT_READ ? SocketListener::Read : SocketListener::Write;

		sockets.push_back(SocketStatus{*sc, flags});
	}

	return sockets;
}
Пример #7
0
void UDDSocket::open(const char* localPath)
{
	// create
	mSocketFD = socket(AF_UNIX,SOCK_DGRAM,0);
	if (mSocketFD<0) {
		perror("socket() failed");
		throw SocketError();
	}
	// Set "close on exec" flag to avoid open sockets inheritance by
	// child processes, like 'transceiver'.
	int flags = fcntl(mSocketFD, F_GETFD);
	if (flags >= 0) fcntl(mSocketFD, F_SETFD, flags | FD_CLOEXEC);

	// bind
	struct sockaddr_un address;
	size_t length = sizeof(address);
	bzero(&address,length);
	address.sun_family = AF_UNIX;
	strcpy(address.sun_path,localPath);
	unlink(localPath);
	if (bind(mSocketFD,(struct sockaddr*)&address,length)<0) {
		perror("bind() failed");
		throw SocketError();
	}
}
Пример #8
0
void UDPSocket::open(unsigned short localPort)
{
	// create
	mSocketFD = socket(AF_INET,SOCK_DGRAM,0);
	if (mSocketFD<0) {
		perror("socket() failed");
		devassert(0);
		throw SocketError();
	}

	// pat added: This lets the socket be reused immediately, which is needed if OpenBTS crashes.
	int on = 1;
	setsockopt(mSocketFD, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));


	// bind
	struct sockaddr_in address;
	size_t length = sizeof(address);
	bzero(&address,length);
	address.sin_family = AF_INET;
	address.sin_addr.s_addr = INADDR_ANY;
	address.sin_port = htons(localPort);
	if (bind(mSocketFD,(struct sockaddr*)&address,length)<0) {
		char buf[100];
		sprintf(buf,"bind(port %d) failed",localPort);
		perror(buf);
		devassert(0);
		throw SocketError();
	}
}
Пример #9
0
result_t Socket::create(int32_t family, int32_t type)
{
    if (m_sock != INVALID_SOCKET)
    {
        if (exlib::Service::hasService())
            ac_close();
        else
        {
            asyncEvent ac;
            close(&ac);
        }
    }

    m_family = family;
    m_type = type;

    if (family == net_base::_AF_INET)
        family = AF_INET;
    else if (family == net_base::_AF_INET6)
        family = AF_INET6;
    else
        return CHECK_ERROR(CALL_E_INVALIDARG);

    if (type == net_base::_SOCK_STREAM)
        type = SOCK_STREAM;
    else if (type == net_base::_SOCK_DGRAM)
        type = SOCK_DGRAM;
    else
        return CHECK_ERROR(CALL_E_INVALIDARG);

#ifdef _WIN32

    m_sock = WSASocket(family, type, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED);
    if (m_sock == INVALID_SOCKET)
        return CHECK_ERROR(SocketError());

    CreateIoCompletionPort((HANDLE) m_sock, s_hIocp, 0, 0);

#else

    m_sock = socket(family, type, 0);
    if (m_sock == INVALID_SOCKET)
        return CHECK_ERROR(SocketError());

    fcntl(m_sock, F_SETFL, fcntl(m_sock, F_GETFL, 0) | O_NONBLOCK);
    fcntl(m_sock, F_SETFD, FD_CLOEXEC);

#endif

#ifdef MacOS

    int set_option = 1;
    setsockopt(m_sock, SOL_SOCKET, SO_NOSIGPIPE, &set_option,
               sizeof(set_option));

#endif

    return 0;
}
Пример #10
0
int SocketClient::recv(char *buf, int len) throw (SocketError) {
    int ret = ::recv(cfd, buf, len, 0);
    if (ret <= 0) {
        throw SocketError(cfd, errno, strerror(errno));
    }
    else if (ret == 0) {
        throw SocketError(cfd, EREMOTEIO, "remote client closed");
    }
    return ret;
}
Пример #11
0
std::vector<SocketStatus> Select::wait(const SocketTable &table, int ms)
{
	timeval maxwait, *towait;
	fd_set readset;
	fd_set writeset;

	FD_ZERO(&readset);
	FD_ZERO(&writeset);

	SocketAbstract::Handle max = 0;

	for (const auto &s : table) {
		if (s.second.second & SocketListener::Read) {
			FD_SET(s.first, &readset);
		}
		if (s.second.second & SocketListener::Write) {
			FD_SET(s.first, &writeset);
		}

		if (s.first > max) {
			max = s.first;
		}
	}

	maxwait.tv_sec = 0;
	maxwait.tv_usec = ms * 1000;

	// Set to nullptr for infinite timeout.
	towait = (ms < 0) ? nullptr : &maxwait;

	auto error = ::select(max + 1, &readset, &writeset, nullptr, towait);
	if (error == SocketAbstract::Error) {
		throw SocketError(SocketError::System, "select");
	}
	if (error == 0) {
		throw SocketError(SocketError::Timeout, "select", "Timeout while listening");
	}

	std::vector<SocketStatus> sockets;

	for (auto &c : table) {
		if (FD_ISSET(c.first, &readset)) {
			sockets.push_back(SocketStatus{*c.second.first, SocketListener::Read});
		}
		if (FD_ISSET(c.first, &writeset)) {
			sockets.push_back(SocketStatus{*c.second.first, SocketListener::Write});
		}
	}

	return sockets;
}
Пример #12
0
uint32 SocketPeek(TSocket *s, char *buffer, uint32 len)
{
	int32 r=recv(*s,buffer,len,MSG_PEEK);

	if (r==(-1))
#ifdef _WIN32
		if (SocketError()==WSAEMSGSIZE)
#else
		if (SocketError()==EMSGSIZE)
#endif
			return len;

	return r;
}
Пример #13
0
int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        throw SocketError();
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
        throw SocketError();
    while(1) {
        printf("Please enter the message: ");
        bzero(buffer,256);
        fgets(buffer,255,stdin);
        n = write(sockfd,buffer,strlen(buffer));
        if (n < 0)
			throw SocketError();
            bzero(buffer,256);
            n = read(sockfd,buffer,255);
        if (n < 0)
			throw SocketError();
	    if( strcmp(buffer, "quit") == 0 || strcmp(buffer, "QUIT") == 0 ) {
			printf("QUIT command received. Bye!\n");
			break;
		}
        printf("%s\n",buffer);
}
    close(sockfd);
    return 0;
}
Пример #14
0
        virtual result_t process()
        {
            static LPFN_CONNECTEX ConnectEx;
            int nError;

            if (!ConnectEx)
            {
                GUID guidConnectEx = WSAID_CONNECTEX;
                DWORD dwBytes;

                if (SOCKET_ERROR
                        == WSAIoctl(m_s, SIO_GET_EXTENSION_FUNCTION_POINTER,
                                    &guidConnectEx, sizeof(guidConnectEx),
                                    &ConnectEx, sizeof(ConnectEx), &dwBytes, NULL,
                                    NULL))
                    return CHECK_ERROR(SocketError());
            }

            if (ConnectEx(m_s, (sockaddr *) &m_ai, (int) m_ai.size(), NULL, 0,
                          NULL, this))
                return CHECK_ERROR(CALL_E_PENDDING);

            nError = WSAGetLastError();
            return CHECK_ERROR((nError == WSA_IO_PENDING) ? CALL_E_PENDDING : -nError);
        }
Пример #15
0
/** \brief read the given number of bytes 
 *
 * Read size bytes into the buffer. Wait until size Bytes are available
 * data maight be lossed, if size is smaller then the incomming package.
 * This situation will not be treated as an error.
 *
 * \param buf   Pointer to the data buffer.
 * \param size  Maximum count of bytes to read.
 * \param from  Will be overwritten with the address of the sender
 *
 * \see Socket::recvAvailable Socket::recv
 */
int DgramSocket::recvFrom(void *buf,int size,Address &from)
{
    int len;
    SocketLenT addrLen=from.getSockAddrSize();

    len=recvfrom(_sd,
                 (char*)buf,
                 size,
                 0,
                 from.getSockAddr(),
                 &addrLen);
    if(len<0)
    {
#if defined WIN32
        if(getError()==WSAECONNRESET)
        {
            throw SocketConnReset("recvfrom");
        }
        if(getError()==WSAEMSGSIZE)
        {
            len=size;
        }
        else
#endif
        throw SocketError("recvfrom()");
    }
    return len;
}
Пример #16
0
//////////////////////////////////////////////////////////////////////////
//远程CMD窗口过程
//////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK CmdDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_COMMAND:
		{
			switch(LOWORD(wParam))
			{
			case IDC_BUTTON1:
				{
					//发送远程CMD命令要求
					CmdRequest(sockfd,hDlg);
				}
				break;
			}
		}
		break;
	case WM_SOCKET:
		{
			switch(LOWORD(lParam))
			{
			case FD_WRITE:
				{
					//继续发送
					SendCmd(sockfd,NULL,NULL);
				}
				break;
			case FD_READ:
				{
					RecvCmd(sockfd);
				}
				break;
			case FD_CLOSE:
				{
					//SOCKET出错处理,MainFunc.H里 清理缓冲区
					SocketError(sockfd);
					EndDialog(hDlg,NULL);
				}
				break;
			}
		}
		break;
	case WM_INITDIALOG:
		{
			sockfd = (SOCKET)lParam;
			//非拥塞模式
			WSAAsyncSelect(sockfd,hDlg,WM_SOCKET,FD_WRITE|FD_READ|FD_CLOSE);
		}
		break;
	case WM_CLOSE:
		{
			EndDialog(hDlg,NULL);
		}
		break;
	default:
		break;
	}

	return FALSE;
}
Пример #17
0
Kqueue::Kqueue()
	: m_handle(kqueue())
{
	if (m_handle < 0) {
		throw SocketError(SocketError::System, "kqueue");
	}
}
Пример #18
0
APIRET RSOCKET::bind(ULONG ulIPAddress)
{  
  DEBUG("\nDEBUG: RSOCKET::bind(%08x)",ulIPAddress);	

  sockaddr_in sinAddress;

  sinAddress.sin_family           = AF_INET;
  sinAddress.sin_port             = htons((unsigned short)ulPort);
#ifdef _WIN32
  sinAddress.sin_addr.S_un.S_addr = htonl(ulIPAddress);
#endif

#ifdef __OS2__
  sinAddress.sin_addr.s_addr = htonl(ulIPAddress);
#endif

  if (::bind (sockSocket,
	          (struct sockaddr *)&sinAddress,
		      sizeof(sinAddress)) == SOCKET_ERROR)
  {
    sockPerf.ulTotalErrors++;                                  /* statistics */
	sockPerf.ulPerfErrors++;

    return (SocketError(sockErrno));      /* return proper API error */
  }
  else
	return (NO_ERROR);                                                 /* OK */
}
Пример #19
0
bool Socket::readToBuffer()
{
	if(file < 0)
		throw InvalidState("Socket is closed.");

	char buffer[64*1024];
	ssize_t readIn = 0;

	do{
		readIn = 0;
		do {
			readBuffer.append(buffer, readIn);
			if(0 < readIn){
				totalReceived += readIn;
				dataReceived();
				if(file == -1) // closed by child class
					return true;
			}
			readIn = ::read(file, buffer, sizeof(buffer));
		} while(0 < readIn);
	} while(readIn < 0 && errno == EINTR);

	if(readIn < 0 && ( errno != EAGAIN /*&& errno != EWOULDBLOCK*/ ) )
		throw SocketError(errno, "Error while reading from socket.");

	return 0 <= readIn; // false if EAGAIN or EWOULDBLOCK happened
}
Пример #20
0
    PacketInfo Client::receivePacket( bool is_nonblocking )
    {
        if ( udp_socket < 0 )
            openSocket();

        int flags = 0;
        if ( is_nonblocking )
            flags |= MSG_DONTWAIT;

        sockaddr_in          peer_address;
        socklen_t            peer_address_size = sizeof( peer_address );
        std::vector<uint8_t> receive_buffer( UDP_RECEIVE_BUFFER_SIZE );
        int                  recv_size = recvfrom( udp_socket,
						   receive_buffer.data(),
						   UDP_RECEIVE_BUFFER_SIZE,
						   flags,
						   reinterpret_cast<sockaddr *>( &peer_address ),
						   &peer_address_size );
        if ( recv_size < 0 ) {
            int error_num = errno;
            if ( error_num == EAGAIN ) {
                PacketInfo info;
                return info;
            }
            std::perror( "cannot recv" );
            throw SocketError( get_error_message( "cannot recv packet", error_num ) );
        }

        PacketInfo info;
        info.source_address = convertAddressBinaryToString( peer_address.sin_addr );
        info.source_port    = ntohs( peer_address.sin_port );
        info.payload        = receive_buffer;
        return info;
    }
Пример #21
0
void BitcoinP2P::connectToNode(bool async)
{
   unique_lock<mutex> lock(connectMutex_, defer_lock);

   if (!lock.try_lock()) //return if another thread is already here
      throw SocketError("another connect attempt is underway");

   connectedPromise_ = unique_ptr<promise<bool>>(new promise<bool>());
   auto connectedFuture = connectedPromise_->get_future();

   auto connectLambda = [this](void)->void
   {
      this->connectLoop();
   };

   thread connectthread(connectLambda);
   if (connectthread.joinable())
      connectthread.detach();

   if (async)
      return;

   connectedFuture.get();

   if (select_except_ != nullptr)
      rethrow_exception(select_except_);

   if (process_except_ != nullptr)
      rethrow_exception(process_except_);
}
Пример #22
0
SocketPtr ServerSocket::AcceptConnection() const
{
    assert(socketId != NET_INVALID_SOCKET_ID);

    errno = 0;
    const NetSocketId newSocket = accept(socketId, nullptr, nullptr);
    if (newSocket == NET_INVALID_SOCKET_ID)
    {
        // Non-blocking call / no request pending
        #ifdef _WIN32
        if (WSAGetLastError() == WSAEWOULDBLOCK)
        {
            return nullptr;
        }
        #else // !_WIN32
        if (errno == EAGAIN)
        {
            return nullptr;
        }
        #endif // _WIN32

        throw SocketError("'accept()' failed with an invalid socketId!");
    }

    return SocketPtr(new Socket(newSocket));
}
Пример #23
0
APIRET RSOCKET::accept(RSOCKET& rsockConnection)
{  
  DEBUG("\nDEBUG: RSOCKET::accept(RSOCKET)");

  SOCKET      sockAccept;                   /* descriptor of accepted socket */
  sockaddr_in sinAddress;
  ULONG       ulAddressLength = sizeof(sinAddress);
    
  sockAccept = ::accept (sockSocket,
                         (struct sockaddr *)&sinAddress,
     	                 (int *)&ulAddressLength);
  if (sockAccept == SOCKET_ERROR)
  {
    sockPerf.ulTotalErrors++;                                  /* statistics */
    sockPerf.ulPerfErrors++;

    return (SocketError(sockErrno));              /* return proper API error */
  }
  else
  {
    rsockConnection.SocketSet(sockAccept);              /* create new socket */
	/* @@@PH copy some more values */
    return (NO_ERROR);                                                 /* OK */
  }
}
Пример #24
0
APIRET RSOCKET::accept(SOCKET      *psockSocket,
                       sockaddr_in *psinAddress,
                       PULONG      pulAddressLength)
{ 
  DEBUG("\nDEBUG: RSOCKET::accept(%08x,%08x, %08x)",psockSocket,psinAddress,pulAddressLength);	
	
  SOCKET      sockAccept;                   /* descriptor of accepted socket */

  if (psockSocket == NULL)                            /* check the parameter */	   
	return (ERROR_INVALID_PARAMETER);               /* raise error condition */
  
  sockAccept = ::accept (sockSocket,
                         (struct sockaddr *)psinAddress,
		         (int *)pulAddressLength);
  if (sockAccept == SOCKET_ERROR)
  {
    sockPerf.ulTotalErrors++;                                  /* statistics */
    sockPerf.ulPerfErrors++;

    *psockSocket = (SOCKET)0;                         /* no socket available */
    return (SocketError(sockErrno));      /* return proper API error */
  }
  else
  {
    *psockSocket = sockAccept;               /* return the socket descriptor */
    return (NO_ERROR);                                                 /* OK */
  }
}
Пример #25
0
Epoll::Epoll()
	: m_handle(epoll_create1(0))
{
	if (m_handle < 0) {
		throw SocketError(SocketError::System, "epoll_create");
	}
}
Пример #26
0
APIRET RSOCKET::connect(ULONG ulIPAddress)
{ 
  DEBUG("\nDEBUG: RSOCKET::connect(%08x)",ulIPAddress);	

  sockaddr_in sinAddress;

  sinAddress.sin_family           = AF_INET;
  sinAddress.sin_port             = htons((unsigned short)ulPort);
#ifdef _WIN32
  sinAddress.sin_addr.S_un.S_addr = htonl(ulIPAddress);
#endif

#ifdef __OS2__
  sinAddress.sin_addr.s_addr = htonl(ulIPAddress);
#endif

  if (bConnected == TRUE)          /* check whether we are already connected */
	return (ERROR_SOCKET_ALREADY_CONNECTED);       /* signal error condition */

  if (::connect (sockSocket,
	             (struct sockaddr *)&sinAddress,
		         sizeof(sinAddress)) == SOCKET_ERROR)
  {   
    sockPerf.ulTotalErrors++;                                  /* statistics */
	sockPerf.ulPerfErrors++;

	return (SocketError(sockErrno));      /* return proper API error */
  }
  else
  {
	bConnected = TRUE;                          /* yes, now we are connected */
	return (NO_ERROR);                                                 /* OK */
  }		   
}
Пример #27
0
 std::size_t SecureSocketImpl::Receive(void *data, std::size_t size)
 {
     int received = SSL_read(m_pimpl->ssl, static_cast<char *>(data), static_cast<int>(size));
     if (received == SOCKET_ERROR)
         throw SocketError("Error while receiving data");
     return static_cast<size_t>(received);
 }
Пример #28
0
bool Socket::writeFromBuffer()
{
	if(file < 0)
		throw InvalidState("Socket is closed.");

	long unsigned written = 0;
	int justWritten = 0;
	do {
		justWritten = 0;
		do {
			written += justWritten;
			justWritten = ::write(file,
					writeBuffer.c_str() + written,
					writeBuffer.length - written);
		} while(0 < justWritten);
	} while(justWritten < 0 && errno == EINTR);
	int errNo = errno;

	totalSent += written;
	writeBuffer.chopFront(written);

	if(justWritten < 0 && (errNo == EPIPE || errNo == ECONNRESET))
		throw SocketClosedByPeer(errNo, "Error after writting % bytes "
				"to socket.", written);

	if(justWritten < 0 && ( errNo != EAGAIN /*&& errNo != EWOULDBLOCK*/))
		throw SocketError(errNo, "Error after writting % bytes "
				"to socket.", written);

	if(closeOnSent && writeBuffer.length == 0)
		close();

	return 0 <= justWritten; // false if EAGAIN or EWOULDBLOCK happened
}
Пример #29
0
/*! Read size bytes into the buffer. Wait until size Bytes are available
    On Dgram sockets data maight be lossed, if size is smaller then the
    incomming package. This situation will not be treated as an error.
    The read bytes will not be removed from the in buffer. A call to
    recv after peek will result in the same data.
    \see recv Socket::recv
 */
int DgramSocket::peekFrom(void *buf,int size,SocketAddress &from)
{
    int len;
    SocketLenT addrLen=from.getSockAddrSize();

    len=recvfrom(_sd,
                 static_cast<char *>(buf),
                 size,
                 MSG_PEEK,
                 from.getSockAddr(),
                 &addrLen);
    if(len == -1)
    {
#if defined WIN32
        if(getError() == WSAECONNRESET)
        {
            throw SocketConnReset("recvfrom");
        }
        if(getError() == WSAEMSGSIZE)
        {
            len=size;
        }
        else
#endif
        throw SocketError("recvfrom()");
    }
    return len;
}
Пример #30
0
/** \brief Start selection
 *
 * Wait for the first read or write flag to be true. All other 
 * flags are cleared.
 *
 * \param duration   Maximum wait time in seconds
 *
 * \return Number of set flags
 */
int Selection::select(double duration)
{
    timeval tVal,*tValP;
    int count;
    
    if(duration<0)
    {
        tValP=NULL;
    }
    else
    {       
        tVal.tv_sec  = int( duration );
        tVal.tv_usec = int( (duration-tVal.tv_sec)*1000000 );
        tValP=&tVal;
    }
    count=::select(FD_SETSIZE, 
                   &_fdSetRead, 
                   &_fdSetWrite,
                   NULL,
                   tValP);
    if(count < 0)
    {
        throw SocketError("select()");
    }
    return count;
}