Sese Framework  x.y.z
A cross-platform framework
载入中...
搜索中...
未找到
Socket.h
浏览该文件的文档.
1// Copyright 2024 libsese
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
22#pragma once
23
25#include "sese/Config.h"
26#include "sese/io/Closeable.h"
27#include "sese/io/Stream.h"
30
31#include <system_error>
32
33#ifdef _WIN32
34#pragma warning(disable : 4251)
35#endif
36
37namespace sese::net {
38
39#ifdef _WIN32
40class SocketInitiateTask final : public InitiateTask {
41public:
42 SocketInitiateTask() : InitiateTask(__FUNCTION__) {}
43
44 int32_t init() noexcept override;
45 int32_t destroy() noexcept override;
46};
47#endif
48
52class Socket : public io::Stream, public io::PeekableStream, public io::Closeable {
53public:
54 using Ptr = std::shared_ptr<Socket>;
55
57 enum class Type {
59 TCP = SOCK_STREAM,
61 UDP = SOCK_DGRAM
62 };
63
65 enum class Family {
67 IPv4 = AF_INET,
69 IPv6 = AF_INET6
70 };
71
73 enum class ShutdownMode {
74#ifdef _WIN32
76 READ = 0,
78 WRITE = 1,
80 BOTH = 2
81#else
82 READ = SHUT_RD,
83 WRITE = SHUT_WR,
84 BOTH = SHUT_RDWR
85#endif
86 };
87
88public:
89 Socket(Family family, Type type, int32_t protocol = IPPROTO_IP) noexcept;
90 Socket(socket_t handle, Address::Ptr address) noexcept;
91 ~Socket() noexcept override;
92
93public:
94 virtual int32_t bind(Address::Ptr address) noexcept;
95 virtual int32_t connect(Address::Ptr address) noexcept;
96 virtual int32_t listen(int32_t backlog) const noexcept; /* NOLINT */
97 [[nodiscard]] virtual Socket::Ptr accept() const;
98 virtual int32_t shutdown(ShutdownMode mode) const; /* NOLINT */
99 bool setNonblocking() const noexcept; /* NOLINT */
106 int64_t read(void *buffer, size_t length) override;
113 int64_t write(const void *buffer, size_t length) override;
122 int64_t send(void *buffer, size_t length, const IPAddress::Ptr &to, int32_t flags) const;
131 int64_t recv(void *buffer, size_t length, const IPAddress::Ptr &from, int32_t flags) const;
132
133public:
134 int64_t peek(void *buffer, size_t length) override;
135
136 int64_t trunc(size_t length) override;
137
138public:
139#define W(func) \
140 value = func(value); \
141 return write(&value, sizeof(value));
142 int64_t writeInt16(int16_t value){W(ToBigEndian16)} int64_t writeInt32(int32_t value){W(ToBigEndian32)} int64_t writeInt64(int64_t value){W(ToBigEndian64)} int64_t writeUint16(uint16_t value){W(ToBigEndian16)} int64_t writeUint32(uint32_t value){W(ToBigEndian32)} int64_t writeUint64(uint64_t value){W(ToBigEndian64)}
143#undef W
144#define R(func) \
145 auto len = read(&value, sizeof(value)); \
146 value = func(value); \
147 return len;
148 int64_t readInt16(int16_t &value){R(FromBigEndian16)} int64_t readInt32(int32_t &value){R(FromBigEndian32)} int64_t readInt64(int64_t &value){R(FromBigEndian64)} int64_t readUint16(uint16_t &value){R(FromBigEndian16)} int64_t readUint32(uint32_t &value){R(FromBigEndian32)} int64_t readUint64(uint64_t &value) {
150 }
151#undef R
152
153 void close() override;
154 [[nodiscard]] const socket_t &getRawSocket() const { return handle; }
155 [[nodiscard]] const Address::Ptr &getAddress() const { return address; }
156
157private:
158 socket_t handle{};
160
161public:
162 static socket_t socket(int family, int type, int protocol) noexcept;
163
164 static int bind(socket_t socket, const sockaddr *addr, socklen_t addr_len) noexcept;
165
166 static socket_t accept(socket_t socket, sockaddr *addr = nullptr, socklen_t *len = nullptr) noexcept;
167
168 static int connect(socket_t socket, const sockaddr *addr, socklen_t addr_len) noexcept;
169
170 static int64_t write(socket_t socket, const void *buffer, size_t len, int flags) noexcept;
171
172 static int64_t read(socket_t socket, void *buffer, size_t len, int flags) noexcept;
173
174 static int listen(socket_t socket, int backlog) noexcept;
175
176 static int setNonblocking(socket_t socket) noexcept;
177
178 static void close(socket_t socket) noexcept;
179
180 static int shutdown(socket_t socket, ShutdownMode mode) noexcept;
181};
182
187uint16_t createRandomPort() noexcept;
188
193extern int getNetworkError() noexcept;
194
200std::string getNetworkErrorString(int error = getNetworkError()) noexcept;
201
202} // namespace sese::net