24#include <glog/logging.h>
35int RecvInternal(
int fd,
void* buf,
size_t len) {
38 int ret = recv(fd, (
char*)buf + pos, len, 0);
51int SendInternal(
int fd,
const void* buf,
size_t len) {
57 int ret = send(fd, (
char*)buf + pos, len - pos, 0);
59 LOG(ERROR) <<
"send data fail, fd =" << fd <<
" error "
82 if (socket_fd_ >= 0) {
88int TcpSocket::InitSocket() {
89 if ((socket_fd_ = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
90 LOG(ERROR) <<
"create TcpSocket error: " << strerror(errno)
91 <<
" (errno: " << errno <<
")";
99 if (setsockopt(socket_fd_, SOL_SOCKET, SO_REUSEADDR, &on,
sizeof(on)) != 0) {
100 LOG(ERROR) <<
"set TcpSocket opt fail, error" << strerror(errno);
104 struct sockaddr_in servaddr;
105 memset(&servaddr, 0,
sizeof(servaddr));
106 servaddr.sin_family = AF_INET;
107 servaddr.sin_addr.s_addr = inet_addr(ip.data());
108 servaddr.sin_port = htons(port);
110 if (bind(socket_fd_, (
struct sockaddr*)&servaddr,
sizeof(servaddr)) == -1) {
111 LOG(ERROR) <<
"bind TcpSocket error: " << strerror(errno)
112 <<
"(errno: " << errno <<
")";
116 if (listen(socket_fd_, 10) == -1) {
117 LOG(ERROR) <<
"listen TcpSocket error: " << strerror(errno)
118 <<
"(errno: " << errno <<
")";
122 struct sockaddr_in localaddr;
123 socklen_t len =
sizeof(localaddr);
124 int ret = getsockname(socket_fd_, (
struct sockaddr*)&localaddr, &len);
126 LOG(ERROR) <<
"get binding port fail:" << strerror(errno);
128 binding_port_ = ntohs(localaddr.sin_port);
131 binding_port_ = port;
140 if ((conn_fd = accept(socket_fd_, (
struct sockaddr*)NULL, NULL)) == -1) {
147 return std::make_unique<TcpSocket>(conn_fd);
151 if (socket_fd_ < 0) {
152 LOG(ERROR) <<
"socket fd invalid:" << socket_fd_;
155 struct sockaddr_in servaddr;
156 memset(&servaddr, 0,
sizeof(servaddr));
157 servaddr.sin_family = AF_INET;
158 servaddr.sin_addr.s_addr = inet_addr(ip.data());
159 servaddr.sin_port = htons(port);
161 if (connect(socket_fd_, (
struct sockaddr*)&servaddr,
sizeof(servaddr)) < 0) {
162 LOG(ERROR) <<
"fd:" << socket_fd_ <<
" connect ip:" << ip
163 <<
" port:" << port <<
" error: " << strerror(errno)
164 <<
"(errno: " << errno <<
")";
173 unsigned long ul = is_open;
174 return ioctl(socket_fd_, FIONBIO, (
unsigned long*)&ul);
178 size_t data_size =
data.size();
179 size_t send_ret = SendInternal(socket_fd_, &data_size,
sizeof(data_size));
180 if (send_ret !=
sizeof(data_size)) {
181 if (
static_cast<int>(send_ret) == -1) {
182 LOG(ERROR) <<
"send data error: " << strerror(errno)
183 <<
"(errno: " << errno <<
")";
189 send_ret = SendInternal(socket_fd_,
data.c_str(), data_size);
190 if (send_ret != data_size) {
191 if (
static_cast<int>(send_ret) == -1) {
192 LOG(ERROR) <<
"send data not done: " << strerror(errno)
193 <<
"(errno: " << errno <<
")";
203 int ret = RecvInternal(socket_fd_, len,
sizeof(
size_t));
208 ret = RecvInternal(socket_fd_, *buf, *len);
216 if (socket_fd_ < 0) {
219 struct timeval timeout = {microseconds / 1000000,
220 static_cast<int>(microseconds % 1000000)};
221 if (setsockopt(socket_fd_, SOL_SOCKET, SO_RCVTIMEO, (
char*)&timeout,
222 sizeof(
struct timeval)) != 0) {
223 LOG(ERROR) <<
"set recv timeout:" << microseconds
224 <<
" failed:" << strerror(errno);
229 struct timeval timeout = {microseconds / 1000000,
230 static_cast<int>(microseconds % 1000000)};
231 if (setsockopt(socket_fd_, SOL_SOCKET, SO_SNDTIMEO, (
char*)&timeout,
232 sizeof(
struct timeval)) != 0) {
233 LOG(ERROR) <<
"set second timeout failed:" << strerror(errno);
int Connect(const std::string &ip, int port) override
void SetRecvTimeout(int64_t microseconds) override
int Send(const std::string &data) override
int Recv(void **buf, size_t *len) override
int GetBindingPort() override
void SetSendTimeout(int64_t microseconds) override
std::unique_ptr< Socket > Accept() override
int Listen(const std::string &ip, int port) override
int SetAsync(bool is_open=true) override