int32 DatagramChannel::Send(const SocketInetAddress& addr, Buffer* buffer) { char* raw = const_cast<char*>(buffer->GetRawReadBuffer()); uint32 len = buffer->ReadableBytes(); int ret = ::sendto(GetSocketFD(addr.GetDomain()), raw, len, 0, &(addr.GetRawSockAddr()), addr.GetRawSockAddrSize()); if (ret > 0) { buffer->AdvanceReadIndex(len); } return ret; }
int32 DatagramChannel::Receive(SocketInetAddress& addr, Buffer* buffer) { sockaddr& tempaddr = const_cast<sockaddr&>(addr.GetRawSockAddr()); socklen_t socklen = sizeof(sockaddr); memset(&tempaddr, 0, sizeof(struct sockaddr_in)); buffer->EnsureWritableBytes(65536); char* raw = const_cast<char*>(buffer->GetRawWriteBuffer()); int ret = ::recvfrom(GetSocketFD(addr.GetDomain()), raw, buffer->WriteableBytes(), 0, &tempaddr, &socklen); if (ret > 0) { buffer->AdvanceWriteIndex(ret); } return ret; }
bool SocketChannel::DoConnect(Address* remote) { if (NULL == remote) { return false; } SocketInetAddress addr; if (InstanceOf<SocketHostAddress>(remote).OK) { SocketHostAddress* host_addr = static_cast<SocketHostAddress*>(remote); addr = get_inet_address(host_addr->GetHost(), host_addr->GetPort()); } else if (InstanceOf<SocketInetAddress>(remote).OK) { SocketInetAddress* inet_addr = static_cast<SocketInetAddress*>(remote); addr = (*inet_addr); } else if (InstanceOf<SocketUnixAddress>(remote).OK) { SocketUnixAddress* unix_addr = static_cast<SocketUnixAddress*>(remote); addr = get_inet_address(*unix_addr); } else { return false; } int fd = GetSocketFD(addr.GetDomain()); int ret = ::connect(fd, const_cast<sockaddr*>(&(addr.GetRawSockAddr())), addr.GetRawSockAddrSize()); if (ret < 0) { int e = errno; if (((e) == EINTR || (e) == EINPROGRESS)) { //connecting } else { ERROR_LOG("Failed to connect remote server for reason:%s", strerror(e)); return false; } } m_state = SOCK_CONNECTING; //DEBUG_LOG("###Switch to %d", m_state); return true; }
bool SocketChannel::DoBind(Address* local) { if (NULL == local) { return false; } SocketInetAddress addr; if (InstanceOf<SocketHostAddress>(local).OK) { SocketHostAddress* host_addr = static_cast<SocketHostAddress*>(local); addr = get_inet_address(host_addr->GetHost(), host_addr->GetPort()); } else if (InstanceOf<SocketInetAddress>(local).OK) { SocketInetAddress* inet_addr = static_cast<SocketInetAddress*>(local); addr = (*inet_addr); } else if (InstanceOf<SocketUnixAddress>(local).OK) { SocketUnixAddress* unix_addr = (SocketUnixAddress*) local; unlink(unix_addr->GetPath().c_str()); // in case it already exists addr = get_inet_address(*unix_addr); } else { return false; } if (addr.IsUnix()) { struct sockaddr_un* pun = (struct sockaddr_un*) &(addr.GetRawSockAddr()); DEBUG_LOG("Bind on %s", pun->sun_path); } int fd = GetSocketFD(addr.GetDomain()); if (0 == ::bind(fd, &(addr.GetRawSockAddr()), addr.GetRawSockAddrSize())) { return true; } int e = errno; ERROR_LOG("Failed to bind address for reason:%s", strerror(e)); return false; }