forked from skyfireitdiy/sflib
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsf_tcp_client_linux.hpp
More file actions
154 lines (140 loc) · 5.48 KB
/
Copy pathsf_tcp_client_linux.hpp
File metadata and controls
154 lines (140 loc) · 5.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/**
* @version 1.0.0
* @author skyfire
* @mail skyfireitdiy@hotmail.com
* @see http://github.com/skyfireitdiy/sflib
* @file sf_tcp_client_linux.hpp
* sflib第一版本发布
* 版本号1.0.0
* 发布日期:2018-10-22
*/
#pragma once
#include "sf_tcp_client_linux.h"
#include "sf_tcp_utils.hpp"
#include "sf_object.hpp"
#include "sf_nocopy.h"
#include "sf_type.hpp"
#include "sf_tcp_client_interface.hpp"
namespace skyfire
{
inline sf_tcp_client::sf_tcp_client(bool raw) {
sock__ = socket(AF_INET, SOCK_STREAM, 0);
if (sock__ == -1)
{
inited__ = false;
return;
}
int opt = 1;
if (-1 == setsockopt( sock__, SOL_SOCKET,SO_REUSEADDR,
reinterpret_cast<const void *>(&opt), sizeof(opt))){
inited__ = false;
return ;
}
inited__ = true;
raw__ = raw;
}
inline SOCKET sf_tcp_client::get_raw_socket() {
return sock__;
}
inline bool sf_tcp_client::bind(const std::string &ip, unsigned short port) {
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip.c_str());
address.sin_port = htons(port);
return -1 != ::bind(sock__,reinterpret_cast<sockaddr*>(&address), sizeof(address));
}
inline std::shared_ptr<sf_tcp_client> sf_tcp_client::make_client(bool raw) {
return std::make_shared<sf_tcp_client>(raw);
}
inline sf_tcp_client::~sf_tcp_client() {
close();
}
inline bool sf_tcp_client::connect_to_server(const std::string &ip, unsigned short port) {
if (!inited__)
return false;
sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(ip.c_str());
address.sin_port = htons(port);
if (::connect(sock__, reinterpret_cast<const sockaddr *>(&address), sizeof(address)) != 0)
{
return false;
}
std::thread([=]
{
byte_array recv_buffer(SF_NET_BUFFER_SIZE);
byte_array data;
sf_pkg_header_t header;
while (true)
{
auto len = read(sock__, recv_buffer.data(), SF_NET_BUFFER_SIZE);
if (len <= 0)
{
closed();
break;
}
if(raw__)
{
raw_data_coming(byte_array(recv_buffer.begin(),recv_buffer.begin() + len));
}
else
{
data.insert(data.end(), recv_buffer.begin(), recv_buffer.begin() + len);
size_t read_pos = 0;
while (data.size() - read_pos >= sizeof(sf_pkg_header_t))
{
std::memmove(&header, data.data() + read_pos, sizeof(header));
if (!check_header_checksum(header))
{
close();
return;
}
if (data.size() - read_pos - sizeof(header) >= header.length)
{
data_coming(
header,
byte_array(
data.begin() + static_cast<long>(read_pos) + sizeof(header),
data.begin() + static_cast<long>(read_pos) + sizeof(header)
+ static_cast<long>(header.length)));
read_pos += sizeof(header) + header.length;
}
else
{
break;
}
}
if (read_pos != 0)
{
data.erase(data.begin(), data.begin() + static_cast<long>(read_pos));
}
}
}
}).detach();
return true;
}
inline bool sf_tcp_client::send(int type, const byte_array &data) {
if (!inited__)
return false;
sf_pkg_header_t header;
header.type = type;
header.length = data.size();
make_header_checksum(header);
auto ret = write(sock__, make_pkg(header).data(), sizeof(header));
if (ret != sizeof(header))
return false;
return write(sock__, data.data(), data.size()) == static_cast<ssize_t>(data.size());
}
inline bool sf_tcp_client::send(const byte_array &data) {
if (!inited__)
return false;
return write(sock__, data.data(), data.size()) == static_cast<ssize_t>(data.size());
}
inline void sf_tcp_client::close() {
if (!inited__)
return;
shutdown(sock__,SHUT_RDWR);
::close(sock__);
sock__ = -1;
}
}