Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
code
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ReadMailReallyFast
code
Commits
b9204190
Commit
b9204190
authored
4 years ago
by
Leon Dietrich
Browse files
Options
Downloads
Patches
Plain Diff
add: ctors for tcp_client to connecto to remote server
parent
9463c054
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/net/tcp_client.cpp
+90
-3
90 additions, 3 deletions
src/net/tcp_client.cpp
src/net/tcp_client.hpp
+5
-3
5 additions, 3 deletions
src/net/tcp_client.hpp
with
95 additions
and
6 deletions
src/net/tcp_client.cpp
+
90
−
3
View file @
b9204190
...
...
@@ -8,27 +8,114 @@
#include
"net/tcp_client.hpp"
#include
<ev++.h>
#include
<fcntl.h>
#include
<netdb.h>
#include
<sys/types.h>
#include
<netinet/in.h>
#include
<sys/socket.h>
#include
<utility>
#include
<deque>
#include
"net/netio_exception.hpp"
#include
"net/socketaddress.hpp"
namespace
rmrf
::
net
{
tcp_client
::
tcp_client
(
const
destructor_cb_type
destructor_cb_
,
auto_fd
&&
socket_fd
,
std
::
string
peer_address_
,
uint16_t
port_
)
:
connection_client
{},
destructor_cb
(
destructor_cb_
),
socket
(
std
::
forward
<
auto_fd
>
(
socket_fd
)),
peer_address
(
peer_address_
),
port
(
port_
),
net_socket
(
std
::
forward
<
auto_fd
>
(
socket_fd
)),
io
{},
write_queue
{}
{
io
.
set
<
tcp_client
,
&
tcp_client
::
cb_ev
>
(
this
);
io
.
start
(
this
->
socket
.
get
(),
::
ev
::
READ
);
io
.
start
(
this
->
net_
socket
.
get
(),
::
ev
::
READ
);
// TODO log created client
}
tcp_client
::
tcp_client
(
const
std
::
string
peer_address_
,
std
::
string
service_or_port
,
int
ip_addr_family
)
:
connection_client
{},
destructor_cb
(
nullptr
),
peer_address
(
peer_address_
),
port
(
0
),
net_socket
(
nullfd
),
io
{},
write_queue
{}
{
this
->
net_socket
=
auto_fd
(
socket
(
AF_INET
,
SOCK_STREAM
,
0
));
if
(
!
this
->
net_socket
.
valid
())
{
// TODO implement proper error handling
throw
netio_exception
(
"Failed to request socket fd from kernel."
);
}
if
(
!
(
ip_addr_family
==
AF_UNSPEC
||
ip_addr_family
==
AF_INET
||
ip_addr_family
==
AF_INET6
))
{
throw
netio_exception
(
"Invalid IP address family."
);
}
// TODO build another nice HL structure wrapper for outbound connections
int
status
;
struct
addrinfo
hints
;
struct
addrinfo
*
servinfo
;
memset
(
&
hints
,
0
,
sizeof
hints
);
hints
.
ai_family
=
ip_addr_family
;
hints
.
ai_socktype
=
SOCK_STREAM
;
if
((
status
=
getaddrinfo
(
peer_address_
.
c_str
(),
service_or_port
.
c_str
(),
&
hints
,
&
servinfo
))
!=
0
)
{
throw
netio_exception
(
"Failed to resolve address '"
+
peer_address_
+
"' with service '"
+
service_or_port
+
"': "
+
gai_strerror
(
status
));
}
std
::
deque
<
socketaddr
>
connection_candidates
;
for
(
auto
p
=
servinfo
;
p
!=
NULL
;
p
=
p
->
ai_next
)
{
if
(
p
->
ai_family
==
AF_INET
)
{
struct
sockaddr_in
*
ipv4
=
(
struct
sockaddr_in
*
)
p
->
ai_addr
;
socketaddr
sa
{
ipv4
};
connection_candidates
.
push_back
(
sa
);
}
else
if
(
p
->
ai_family
==
AF_INET6
)
{
struct
sockaddr_in6
*
ipv6
=
(
struct
sockaddr_in6
*
)
p
->
ai_addr
;
socketaddr
sa
{
ipv6
};
connection_candidates
.
push_front
(
sa
);
}
}
freeaddrinfo
(
servinfo
);
status
=
1
;
do
{
if
(
connection_candidates
.
empty
())
{
throw
netio_exception
(
"Unable to find suitable connection candidate."
);
}
socketaddr
socket_identifier
=
connection_candidates
.
front
();
connection_candidates
.
pop_front
();
auto_fd
socket_candidate
{
socket
(
socket_identifier
.
family
(),
SOCK_STREAM
,
0
)};
if
(
socket_candidate
.
valid
())
{
if
(
connect
(
socket_candidate
.
get
(),
socket_identifier
.
ptr
(),
socket_identifier
.
size
())
==
0
)
{
status
=
0
;
this
->
net_socket
=
std
::
forward
<
auto_fd
>
(
socket_candidate
);
fcntl
(
this
->
net_socket
.
get
(),
F_SETFL
,
fcntl
(
this
->
net_socket
.
get
(),
F_GETFL
,
0
)
|
O_NONBLOCK
);
// Hier bin ich mir nicht sicher, wie ich das am besten mache. Auch mit socketaddr und type cast ist das irgendwie doof.
// Das Problem besteht darin, dass erst nach erfolgreichem connect der Port auf dieser Seite bekannt ist.
/*
struct sockaddr_in sin;
if(getsockname(this->net_socket.get(), (struct sockaddr *) &sin, (socklen_t*) &((int) sizeof(sin)))) {
this->port = ntohs(sin.sin_port);
}*/
}
}
// We don't need to worry about closing broken fd as auto_fd handles this for us
}
while
(
status
==
1
);
io
.
set
<
tcp_client
,
&
tcp_client
::
cb_ev
>
(
this
);
io
.
start
(
this
->
net_socket
.
get
(),
::
ev
::
READ
);
//TODO log connected client
}
tcp_client
::
tcp_client
(
const
std
::
string
peer_address_
,
std
::
string
service_or_port
)
:
tcp_client
(
peer_address_
,
service_or_port
,
AF_UNSPEC
)
{
}
tcp_client
::
tcp_client
(
const
std
::
string
peer_address_
,
const
uint16_t
port_
)
:
tcp_client
(
peer_address_
,
std
::
to_string
(
port_
))
{}
tcp_client
::~
tcp_client
()
{
destructor_cb
(
EXIT_STATUS_NO_ERROR
);
if
(
destructor_cb
!=
nullptr
)
destructor_cb
(
EXIT_STATUS_NO_ERROR
);
io
.
stop
();
}
...
...
This diff is collapsed.
Click to expand it.
src/net/tcp_client.hpp
+
5
−
3
View file @
b9204190
...
...
@@ -45,15 +45,17 @@ public:
typedef
std
::
function
<
void
(
exit_status
)
>
destructor_cb_type
;
private:
const
destructor_cb_type
destructor_cb
;
const
auto_fd
socket
;
const
std
::
string
peer_address
;
const
uint16_t
port
;
uint16_t
port
;
auto_fd
net_socket
;
::
ev
::
io
io
;
std
::
list
<
std
::
shared_ptr
<
impl
::
NICBuffer
>>
write_queue
;
public:
tcp_client
(
const
destructor_cb_type
destructor_cb_
,
auto_fd
&&
socket_fd
,
std
::
string
peer_address_
,
uint16_t
port_
);
tcp_client
(
const
std
::
string
);
tcp_client
(
const
std
::
string
peer_address_
,
const
uint16_t
port_
);
tcp_client
(
const
std
::
string
peer_address_
,
std
::
string
service_or_port
);
tcp_client
(
const
std
::
string
peer_address_
,
std
::
string
service_or_port
,
int
ip_addr_family
);
virtual
~
tcp_client
();
virtual
void
write_data
(
std
::
string
data
);
std
::
string
get_peer_address
();
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment