blob: b1ea57677e0a93e5a9573994fff0c6e03a620f96 [file] [log] [blame]
Thomas Psotadb37cb92019-03-11 14:13:06 +01001/*
2 * socket_windows.cpp
3 *
4 * Created on: 06.11.2018
5 * Author: schnicke
6 */
7
Tobias Klausmannf13b5e22019-12-13 11:56:37 +01008#include <BaSyx/abstraction/impl/socket_impl.h>
Thomas Psotadb37cb92019-03-11 14:13:06 +01009
10#include <cstring>
11#include <iostream>
12#include <unistd.h>
13
14namespace basyx {
15namespace net {
16 namespace impl {
17
Thomas Psota2a4cfc72019-05-14 11:30:01 +020018 socket_impl::socket_impl()
19 : SocketDesc { 0 }
20 , log { "SocketImpl" } {};
21
22 socket_impl::socket_impl(native_socket_type socket)
23 : SocketDesc { socket }
24 , log { "SocketImpl" } {};
25
Thomas Psotadb37cb92019-03-11 14:13:06 +010026 socket_impl::~socket_impl()
27 {
Thomas Psota2a4cfc72019-05-14 11:30:01 +020028 if(this->SocketDesc != 0) {
29 this->shutdown(SHUTDOWN_RDWR);
30 this->close();
31 };
Thomas Psotadb37cb92019-03-11 14:13:06 +010032 };
33
34 int socket_impl::connect(std::string const& address, std::string const& port)
35 {
36 struct addrinfo *result = NULL, *ptr = NULL, hints;
37
38 memset(&hints, 0, sizeof(hints));
39
40 hints.ai_family = AF_UNSPEC; //the address family specification. We usually use AF_INET which is for IPv4 format. For IPv6 format you have to use AF_INET6.
41 hints.ai_socktype = SOCK_STREAM; // SOCK_STREAM opens a connection between two distant computers and allows them to communicate: this protocol is called TCP . SOCK_DGRAM, which doesn't open any connection between the computers, but send immediately the message to the ip and port number specified: this protocol is called UDP
42 hints.ai_protocol = IPPROTO_TCP; // The protocol to be used. The possible options for the protocol parameter are specific to the address family and socket type specified.
43
44 // Resolve the server address and port
45 int iResult = getaddrinfo(address.c_str(), port.c_str(), &hints, &result);
46 if (iResult != 0) {
jwendelil45422f3c2020-03-23 17:59:38 +010047 log.error("getaddrinfo() failed! Error code: {}", iResult);
Thomas Psotadb37cb92019-03-11 14:13:06 +010048 return -1;
49 }
50
51 ptr = result;
52
53 // Create a SOCKET for connecting to server
54 this->SocketDesc = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
55 freeaddrinfo(result);
56
57 if (this->SocketDesc < 0) {
jwendelil45422f3c2020-03-23 17:59:38 +010058 log.error("socket() failed! Error code: {}", iResult);
Thomas Psotadb37cb92019-03-11 14:13:06 +010059 return -1;
60 }
61
62 // Connect to server
63 // 1. server socket, 2. socket address information, 3. size of socket address information ( of the second parameter)
64 iResult = ::connect(this->SocketDesc, ptr->ai_addr, (int)ptr->ai_addrlen);
65 if (iResult < 0) {
jwendelil45422f3c2020-03-23 17:59:38 +010066 log.error("connect() failed! Error code: {}", iResult);
Thomas Psotadb37cb92019-03-11 14:13:06 +010067 ::close(this->SocketDesc);
68 return -1;
69 }
70 return 0;
71 }
72
73 int socket_impl::read(void* buf, size_t count)
74 {
75 return ::recv(this->SocketDesc, reinterpret_cast<char*>(buf), count, 0);
76 }
77
78 int socket_impl::recv(void* buf, size_t len, int flags)
79 {
80 return ::recv(this->SocketDesc, reinterpret_cast<char*>(buf), len, flags);
81 }
82
83 int socket_impl::write(void* buf, size_t count)
84 {
85 return ::send(this->SocketDesc, reinterpret_cast<char*>(buf), count, 0);
86 }
87
88 int socket_impl::shutdown(enum SocketShutdownDir how)
89 {
jwendelil45422f3c2020-03-23 17:59:38 +010090 log.trace("Shutting down socket. Code: {}", how);
Thomas Psota2a4cfc72019-05-14 11:30:01 +020091
92 auto iResult = ::shutdown(this->SocketDesc, how);
93 if (iResult < 0) {
jwendelil45422f3c2020-03-23 17:59:38 +010094 log.error("shutdown() failed! Error code: {}", iResult);
Thomas Psotadb37cb92019-03-11 14:13:06 +010095 return -1;
96 }
97 return 0;
98 }
99
100 int socket_impl::close()
101 {
Thomas Psota2a4cfc72019-05-14 11:30:01 +0200102 log.trace("Closing socket");
103 auto iResult = ::close(this->SocketDesc);
104 if (iResult < 0) {
jwendelil45422f3c2020-03-23 17:59:38 +0100105 log.error("close() failed! Error code: {}", iResult);
Thomas Psotadb37cb92019-03-11 14:13:06 +0100106 return -1;
107 }
Thomas Psota2a4cfc72019-05-14 11:30:01 +0200108 this->SocketDesc = 0;
Thomas Psotadb37cb92019-03-11 14:13:06 +0100109 return 0;
110 }
111
112 int socket_impl::getErrorCode()
113 {
114 return errno;
115 }
116
117 //void socket_impl::setDesc(SOCKET fd) {
118 // this->SocketDesc = fd;
119 //}
120 }
121}
122}