mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 06:05:58 -06:00
Core: UnixSocket (AF_UNIX) implementation (#325)
* Core: UnixSocket (AF_UNIX) implementation Core/UnixSocket: GetPeerPid refactored reference/UnixSocketClient: Use default socket type for connection reference/UnixSocketServer: Use default socket type for listen Core: UnixSocket API docs & cleanup Core: UnixSocket friend declaration guarded using ifdefs. * Core: UnixSocket, GetPeerPid() refactored, docs updated * Core: TcpSocket renamed as Socket and added unix domain socket support. Cleanup Updated API docs. * Core: UnixSocket entry removed from API docs. * Core: Socket/SocketWaitEvent API docs cosmetics. * Core: Socket cosmetics
This commit is contained in:
parent
09a272d7f7
commit
962dd7f37c
12 changed files with 537 additions and 184 deletions
51
autotest/UnixSocket/UnixSocket.cpp
Normal file
51
autotest/UnixSocket/UnixSocket.cpp
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
#include <Core/Core.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
CONSOLE_APP_MAIN
|
||||
{
|
||||
#ifdef PLATFORM_POSIX
|
||||
|
||||
StdLogSetup(LOG_COUT|LOG_FILE);
|
||||
|
||||
String path = Format("/tmp/upp-unixsocket-test-%d", getpid());
|
||||
|
||||
Socket server, client;
|
||||
|
||||
// Test server listen
|
||||
if(!server.ListenFileSystem(path)) {
|
||||
LOG("Server listen failed: " << server.GetErrorDesc());
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
// Test client connect
|
||||
if(!client.ConnectFileSystem(path)) {
|
||||
LOG("Client connect failed: " << client.GetErrorDesc());
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
// Test data exchange
|
||||
String test_data = "Hello, world!";
|
||||
client.Put(test_data + "\n");
|
||||
|
||||
Socket accepted;
|
||||
if(!accepted.Accept(server)) {
|
||||
LOG("Accept failed: " << accepted.GetErrorDesc());
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
String received = accepted.GetLine();
|
||||
DUMP(received);
|
||||
|
||||
ASSERT(received == test_data);
|
||||
|
||||
// Test peer PID (on supported platforms)
|
||||
int pid = accepted.GetPeerPid();
|
||||
DUMP(pid);
|
||||
if(pid != -1)
|
||||
ASSERT(pid == getpid()); // Should be our own process in this test
|
||||
|
||||
LOG("=========== OK");
|
||||
|
||||
#endif
|
||||
}
|
||||
9
autotest/UnixSocket/UnixSocket.upp
Normal file
9
autotest/UnixSocket/UnixSocket.upp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
UnixSocket.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
28
reference/UnixSocketClient/UnixSocketClient.cpp
Normal file
28
reference/UnixSocketClient/UnixSocketClient.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include <Core/Core.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
// Start reference/UnixSocketServer before starting this program
|
||||
|
||||
CONSOLE_APP_MAIN
|
||||
{
|
||||
#ifdef PLATFORM_POSIX
|
||||
auto Request = [](const String& r)
|
||||
{
|
||||
Socket s;
|
||||
if(!s.ConnectFileSystem("/tmp/upp-unixsocket.sock")) {
|
||||
Cout() << "Unable to connect to server!\n";
|
||||
SetExitCode(1);
|
||||
return String();
|
||||
}
|
||||
s.Put(r + '\n');
|
||||
return s.GetLine();
|
||||
};
|
||||
|
||||
Cout() << Request("time") << '\n';
|
||||
Cout() << Request("33") << '\n';
|
||||
#else
|
||||
Cout() << "This example requires a POSIX compliant operating system...\r\n"
|
||||
SetExitCode(1);
|
||||
#endif
|
||||
}
|
||||
11
reference/UnixSocketClient/UnixSocketClient.upp
Normal file
11
reference/UnixSocketClient/UnixSocketClient.upp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
description "Example of using client UnixSocket - its counterpart is UnixSocketServer\377";
|
||||
|
||||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
UnixSocketClient.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
33
reference/UnixSocketServer/UnixSocketServer.cpp
Normal file
33
reference/UnixSocketServer/UnixSocketServer.cpp
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
#include <Core/Core.h>
|
||||
|
||||
using namespace Upp;
|
||||
|
||||
CONSOLE_APP_MAIN
|
||||
{
|
||||
#ifdef PLATFORM_POSIX
|
||||
const String& path = "/tmp/upp-unixsocket.sock";
|
||||
|
||||
Socket server;
|
||||
if(!server.ListenFileSystem(path, 5)) {
|
||||
Cout() << "Unable to initialize server socket!\n";
|
||||
SetExitCode(1);
|
||||
return;
|
||||
}
|
||||
Cout() << "Waiting for requests..\n";
|
||||
for(;;) {
|
||||
Socket s;
|
||||
if(s.Accept(server)) {
|
||||
String w = s.GetLine();
|
||||
Cout() << "Request: " << w << " from: " << s.GetPeerPid() << '\n';
|
||||
if(w == "time")
|
||||
s.Put(AsString(GetSysTime()));
|
||||
else
|
||||
s.Put(AsString(3 * atoi(~w)));
|
||||
s.Put("\n");
|
||||
}
|
||||
}
|
||||
#else
|
||||
Cout() << "This example requires a POSIX compliant operating system...\r\n"
|
||||
SetExitCode(1);
|
||||
#endif
|
||||
}
|
||||
11
reference/UnixSocketServer/UnixSocketServer.upp
Normal file
11
reference/UnixSocketServer/UnixSocketServer.upp
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
description "Example of using server UnixSocket - its counterpart is UnixSocketClient\377";
|
||||
|
||||
uses
|
||||
Core;
|
||||
|
||||
file
|
||||
UnixSocketServer.cpp;
|
||||
|
||||
mainconfig
|
||||
"" = "";
|
||||
|
||||
|
|
@ -221,6 +221,7 @@
|
|||
#define W_P(w, p) p
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
//#include <libiberty.h>
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ struct SSLInfo {
|
|||
|
||||
enum { WAIT_READ = 1, WAIT_WRITE = 2, WAIT_IS_EXCEPTION = 4 };
|
||||
|
||||
class TcpSocket : NoCopy {
|
||||
class Socket : NoCopy {
|
||||
enum { BUFFERSIZE = 512 };
|
||||
enum { NONE, CONNECT, ACCEPT, SSL_CONNECTED };
|
||||
SOCKET socket;
|
||||
|
|
@ -136,8 +136,8 @@ class TcpSocket : NoCopy {
|
|||
struct SSLImp;
|
||||
friend struct SSLImp;
|
||||
|
||||
static SSL *(*CreateSSL)(TcpSocket& socket);
|
||||
static SSL *CreateSSLImp(TcpSocket& socket);
|
||||
static SSL *(*CreateSSL)(Socket& socket);
|
||||
static SSL *CreateSSLImp(Socket& socket);
|
||||
|
||||
friend void InitCreateSSL();
|
||||
friend class IpAddrInfo;
|
||||
|
|
@ -172,7 +172,12 @@ class TcpSocket : NoCopy {
|
|||
static int GetErrorCode();
|
||||
static void Init();
|
||||
|
||||
TcpSocket(const TcpSocket&);
|
||||
#ifdef PLATFORM_POSIX // Unix domain socket support
|
||||
bool NixConnect(const String& path, bool abstract);
|
||||
bool NixListen(const String& path, int n, bool reuse, bool abstract);
|
||||
#endif
|
||||
|
||||
Socket(const Socket&);
|
||||
|
||||
public:
|
||||
Event<> WhenWait;
|
||||
|
|
@ -208,10 +213,18 @@ public:
|
|||
bool WaitConnect();
|
||||
bool Listen(int port, int listen_count = 5, bool ipv6 = false, bool reuse = true, void* addr = NULL);
|
||||
bool Listen(const IpAddrInfo& addr, int port, int listen_count = 5, bool ipv6 = false, bool reuse = true);
|
||||
bool Accept(TcpSocket& listen_socket);
|
||||
bool Accept(Socket& listen_socket);
|
||||
void Close();
|
||||
void Shutdown();
|
||||
|
||||
#ifdef PLATFORM_POSIX
|
||||
int GetPeerPid() const;
|
||||
bool ConnectFileSystem(const String& path);
|
||||
bool ConnectAbstract(const String& path);
|
||||
bool ListenFileSystem(const String& path, int listen_count = 5, bool reuse = true);
|
||||
bool ListenAbstract(const String& path, int listen_count = 5, bool reuse = true);
|
||||
#endif
|
||||
|
||||
void NoDelay();
|
||||
void Linger(int msecs);
|
||||
void NoLinger() { Linger(Null); }
|
||||
|
|
@ -247,19 +260,21 @@ public:
|
|||
|
||||
void Clear();
|
||||
|
||||
TcpSocket& Timeout(int ms) { timeout = ms; return *this; }
|
||||
Socket& Timeout(int ms) { timeout = ms; return *this; }
|
||||
int GetTimeout() const { return timeout; }
|
||||
TcpSocket& GlobalTimeout(int ms);
|
||||
TcpSocket& NoGlobalTimeout() { return GlobalTimeout(Null); }
|
||||
TcpSocket& Blocking() { return Timeout(Null); }
|
||||
Socket& GlobalTimeout(int ms);
|
||||
Socket& NoGlobalTimeout() { return GlobalTimeout(Null); }
|
||||
Socket& Blocking() { return Timeout(Null); }
|
||||
bool IsBlocking() { return IsNull(GetTimeout()); }
|
||||
TcpSocket& WaitStep(int ms) { waitstep = ms; return *this; }
|
||||
Socket& WaitStep(int ms) { waitstep = ms; return *this; }
|
||||
int GetWaitStep() const { return waitstep; }
|
||||
|
||||
TcpSocket();
|
||||
~TcpSocket() { Close(); }
|
||||
Socket();
|
||||
virtual ~Socket() { Close(); }
|
||||
};
|
||||
|
||||
using TcpSocket = Socket; // Backward compatibility
|
||||
|
||||
class SocketWaitEvent {
|
||||
Vector<Tuple<int, dword>> socket;
|
||||
fd_set read[1], write[1], exception[1];
|
||||
|
|
@ -268,7 +283,7 @@ class SocketWaitEvent {
|
|||
public:
|
||||
void Clear() { socket.Clear(); }
|
||||
void Add(SOCKET s, dword events) { socket.Add(MakeTuple((int)s, events)); }
|
||||
void Add(TcpSocket& s, dword events) { Add(s.GetSOCKET(), events); }
|
||||
void Add(Socket& s, dword events) { Add(s.GetSOCKET(), events); }
|
||||
int Wait(int timeout);
|
||||
dword Get(int i) const;
|
||||
dword operator[](int i) const { return Get(i); }
|
||||
|
|
|
|||
|
|
@ -81,13 +81,13 @@ static void *SslRealloc(void *ptr, size_t size)
|
|||
|
||||
#endif
|
||||
|
||||
void TcpSocketInit();
|
||||
void SocketInit();
|
||||
|
||||
INITIALIZER(SSL)
|
||||
{
|
||||
MemoryIgnoreLeaksBlock __;
|
||||
LLOG("SslInit");
|
||||
TcpSocketInit();
|
||||
SocketInit();
|
||||
#ifdef UPP_HEAP
|
||||
#ifndef flagSSL_USEMALLOC // do not change OpenSSL memory functions to U++ heap
|
||||
#ifndef _DEBUG // temporary solution unless we find the source of all those harmless leaks
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ void IpAddrInfo::Clear()
|
|||
|
||||
IpAddrInfo::IpAddrInfo()
|
||||
{
|
||||
TcpSocket::Init();
|
||||
Socket::Init();
|
||||
entry = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -169,12 +169,12 @@ IpAddrInfo::IpAddrInfo()
|
|||
|
||||
#define SOCKERR(x) x
|
||||
|
||||
const char *TcpSocketErrorDesc(int code)
|
||||
const char *SocketErrorDesc(int code)
|
||||
{
|
||||
return strerror(code);
|
||||
}
|
||||
|
||||
int TcpSocket::GetErrorCode()
|
||||
int Socket::GetErrorCode()
|
||||
{
|
||||
return errno;
|
||||
}
|
||||
|
|
@ -183,7 +183,7 @@ int TcpSocket::GetErrorCode()
|
|||
|
||||
#define SOCKERR(x) WSA##x
|
||||
|
||||
const char *TcpSocketErrorDesc(int code)
|
||||
const char *SocketErrorDesc(int code)
|
||||
{
|
||||
static Tuple<int, const char *> err[] = {
|
||||
{ WSAEINTR, "Interrupted function call." },
|
||||
|
|
@ -194,13 +194,13 @@ const char *TcpSocketErrorDesc(int code)
|
|||
{ WSAEWOULDBLOCK, "Resource temporarily unavailable." },
|
||||
{ WSAEINPROGRESS, "Operation now in progress." },
|
||||
{ WSAEALREADY, "Operation already in progress." },
|
||||
{ WSAENOTSOCK, "TcpSocket operation on nonsocket." },
|
||||
{ WSAENOTSOCK, "Socket operation on nonsocket." },
|
||||
{ WSAEDESTADDRREQ, "Destination address required." },
|
||||
{ WSAEMSGSIZE, "Message too long." },
|
||||
{ WSAEPROTOTYPE, "Protocol wrong type for socket." },
|
||||
{ WSAENOPROTOOPT, "Bad protocol option." },
|
||||
{ WSAEPROTONOSUPPORT, "Protocol not supported." },
|
||||
{ WSAESOCKTNOSUPPORT, "TcpSocket type not supported." },
|
||||
{ WSAESOCKTNOSUPPORT, "Socket type not supported." },
|
||||
{ WSAEOPNOTSUPP, "Operation not supported." },
|
||||
{ WSAEPFNOSUPPORT, "Protocol family not supported." },
|
||||
{ WSAEAFNOSUPPORT, "Address family not supported by protocol family." },
|
||||
|
|
@ -212,8 +212,8 @@ const char *TcpSocketErrorDesc(int code)
|
|||
{ WSAECONNABORTED, "Software caused connection abort." },
|
||||
{ WSAECONNRESET, "Connection reset by peer." },
|
||||
{ WSAENOBUFS, "No buffer space available." },
|
||||
{ WSAEISCONN, "TcpSocket is already connected." },
|
||||
{ WSAENOTCONN, "TcpSocket is not connected." },
|
||||
{ WSAEISCONN, "Socket is already connected." },
|
||||
{ WSAENOTCONN, "Socket is not connected." },
|
||||
{ WSAESHUTDOWN, "Cannot send after socket shutdown." },
|
||||
{ WSAETIMEDOUT, "Connection timed out." },
|
||||
{ WSAECONNREFUSED, "Connection refused." },
|
||||
|
|
@ -235,14 +235,14 @@ const char *TcpSocketErrorDesc(int code)
|
|||
return x ? x->b : "Unknown error code.";
|
||||
}
|
||||
|
||||
int TcpSocket::GetErrorCode()
|
||||
int Socket::GetErrorCode()
|
||||
{
|
||||
return WSAGetLastError();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void TcpSocketInit()
|
||||
void SocketInit()
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
ONCELOCK {
|
||||
|
|
@ -255,12 +255,12 @@ void TcpSocketInit()
|
|||
#endif
|
||||
}
|
||||
|
||||
void TcpSocket::Init()
|
||||
void Socket::Init()
|
||||
{
|
||||
TcpSocketInit();
|
||||
SocketInit();
|
||||
}
|
||||
|
||||
void TcpSocket::Reset()
|
||||
void Socket::Reset()
|
||||
{
|
||||
LLOG("Reset");
|
||||
is_eof = false;
|
||||
|
|
@ -280,7 +280,7 @@ void TcpSocket::Reset()
|
|||
ssl_start = Null;
|
||||
}
|
||||
|
||||
TcpSocket::TcpSocket()
|
||||
Socket::Socket()
|
||||
{
|
||||
ClearError();
|
||||
Reset();
|
||||
|
|
@ -289,7 +289,7 @@ TcpSocket::TcpSocket()
|
|||
asn1 = false;
|
||||
}
|
||||
|
||||
bool TcpSocket::SetupSocket()
|
||||
bool Socket::SetupSocket()
|
||||
{
|
||||
#ifdef PLATFORM_WIN32
|
||||
connection_start = msecs();
|
||||
|
|
@ -310,7 +310,7 @@ bool TcpSocket::SetupSocket()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TcpSocket::Open(int family, int type, int protocol)
|
||||
bool Socket::Open(int family, int type, int protocol)
|
||||
{
|
||||
Init();
|
||||
Close();
|
||||
|
|
@ -319,11 +319,11 @@ bool TcpSocket::Open(int family, int type, int protocol)
|
|||
SetSockError("open");
|
||||
return false;
|
||||
}
|
||||
LLOG("TcpSocket::Data::Open() -> " << (int)socket);
|
||||
LLOG("Socket::Data::Open() -> " << (int)socket);
|
||||
return SetupSocket();
|
||||
}
|
||||
|
||||
bool TcpSocket::Listen(int port, int listen_count, bool ipv6_, bool reuse, void *addr)
|
||||
bool Socket::Listen(int port, int listen_count, bool ipv6_, bool reuse, void *addr)
|
||||
{
|
||||
Close();
|
||||
Init();
|
||||
|
|
@ -368,13 +368,13 @@ bool TcpSocket::Listen(int port, int listen_count, bool ipv6_, bool reuse, void
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TcpSocket::Listen(const IpAddrInfo& addr, int port, int listen_count, bool ipv6, bool reuse)
|
||||
bool Socket::Listen(const IpAddrInfo& addr, int port, int listen_count, bool ipv6, bool reuse)
|
||||
{
|
||||
addrinfo *a = addr.GetResult();
|
||||
return Listen(port, listen_count, ipv6, reuse, &(((sockaddr_in*)a->ai_addr)->sin_addr.s_addr));
|
||||
}
|
||||
|
||||
bool TcpSocket::Accept(TcpSocket& ls)
|
||||
bool Socket::Accept(Socket& ls)
|
||||
{
|
||||
Close();
|
||||
Init();
|
||||
|
|
@ -399,7 +399,7 @@ bool TcpSocket::Accept(TcpSocket& ls)
|
|||
return SetupSocket();
|
||||
}
|
||||
|
||||
String TcpSocket::GetPeerAddr() const
|
||||
String Socket::GetPeerAddr() const
|
||||
{
|
||||
if(!IsOpen())
|
||||
return Null;
|
||||
|
|
@ -417,7 +417,7 @@ String TcpSocket::GetPeerAddr() const
|
|||
#endif
|
||||
}
|
||||
|
||||
void TcpSocket::NoDelay()
|
||||
void Socket::NoDelay()
|
||||
{
|
||||
ASSERT(IsOpen());
|
||||
int __true = 1;
|
||||
|
|
@ -426,7 +426,7 @@ void TcpSocket::NoDelay()
|
|||
SetSockError("setsockopt(TCP_NODELAY)");
|
||||
}
|
||||
|
||||
void TcpSocket::Linger(int msecs)
|
||||
void Socket::Linger(int msecs)
|
||||
{
|
||||
ASSERT(IsOpen());
|
||||
linger ls;
|
||||
|
|
@ -436,13 +436,13 @@ void TcpSocket::Linger(int msecs)
|
|||
SetSockError("setsockopt(SO_LINGER)");
|
||||
}
|
||||
|
||||
void TcpSocket::Attach(SOCKET s)
|
||||
void Socket::Attach(SOCKET s)
|
||||
{
|
||||
Close();
|
||||
socket = s;
|
||||
}
|
||||
|
||||
bool TcpSocket::RawConnect(addrinfo *arp)
|
||||
bool Socket::RawConnect(addrinfo *arp)
|
||||
{
|
||||
if(!arp) {
|
||||
SetSockError("connect", -1, "not found");
|
||||
|
|
@ -462,7 +462,7 @@ bool TcpSocket::RawConnect(addrinfo *arp)
|
|||
}
|
||||
if(err.GetCount())
|
||||
err << '\n';
|
||||
err << TcpSocketErrorDesc(GetErrorCode());
|
||||
err << SocketErrorDesc(GetErrorCode());
|
||||
Close();
|
||||
}
|
||||
rp = rp->ai_next;
|
||||
|
|
@ -473,7 +473,7 @@ bool TcpSocket::RawConnect(addrinfo *arp)
|
|||
}
|
||||
|
||||
|
||||
bool TcpSocket::Connect(IpAddrInfo& info)
|
||||
bool Socket::Connect(IpAddrInfo& info)
|
||||
{
|
||||
LLOG("Connect addrinfo");
|
||||
Init();
|
||||
|
|
@ -482,7 +482,7 @@ bool TcpSocket::Connect(IpAddrInfo& info)
|
|||
return RawConnect(result);
|
||||
}
|
||||
|
||||
bool TcpSocket::Connect(const char *host, int port)
|
||||
bool Socket::Connect(const char *host, int port)
|
||||
{
|
||||
LLOG("Connect(" << host << ':' << port << ')');
|
||||
Close();
|
||||
|
|
@ -496,7 +496,7 @@ bool TcpSocket::Connect(const char *host, int port)
|
|||
return Connect(info);
|
||||
}
|
||||
|
||||
bool TcpSocket::WaitConnect()
|
||||
bool Socket::WaitConnect()
|
||||
{
|
||||
if(WaitWrite()) {
|
||||
int optval = 0;
|
||||
|
|
@ -505,7 +505,7 @@ bool TcpSocket::WaitConnect()
|
|||
if (optval == 0)
|
||||
return true;
|
||||
else {
|
||||
SetSockError("wait connect", -1, Nvl(String(TcpSocketErrorDesc(optval)), "failed"));
|
||||
SetSockError("wait connect", -1, Nvl(String(SocketErrorDesc(optval)), "failed"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -513,7 +513,7 @@ bool TcpSocket::WaitConnect()
|
|||
return false;
|
||||
}
|
||||
|
||||
void TcpSocket::RawClose()
|
||||
void Socket::RawClose()
|
||||
{
|
||||
LLOG("close " << (int)socket);
|
||||
if(socket != INVALID_SOCKET) {
|
||||
|
|
@ -531,7 +531,7 @@ void TcpSocket::RawClose()
|
|||
}
|
||||
}
|
||||
|
||||
void TcpSocket::Close()
|
||||
void Socket::Close()
|
||||
{
|
||||
if(ssl)
|
||||
ssl->Close();
|
||||
|
|
@ -540,7 +540,7 @@ void TcpSocket::Close()
|
|||
ssl.Clear();
|
||||
}
|
||||
|
||||
bool TcpSocket::WouldBlock()
|
||||
bool Socket::WouldBlock()
|
||||
{
|
||||
int c = GetErrorCode();
|
||||
#ifdef PLATFORM_POSIX
|
||||
|
|
@ -559,7 +559,7 @@ bool TcpSocket::WouldBlock()
|
|||
#endif
|
||||
}
|
||||
|
||||
int TcpSocket::RawSend(const void *buf, int amount)
|
||||
int Socket::RawSend(const void *buf, int amount)
|
||||
{
|
||||
#ifdef PLATFORM_LINUX
|
||||
int res = send(socket, (const char *)buf, amount, MSG_NOSIGNAL);
|
||||
|
|
@ -574,21 +574,21 @@ int TcpSocket::RawSend(const void *buf, int amount)
|
|||
return res;
|
||||
}
|
||||
|
||||
int TcpSocket::Send(const void *buf, int amount)
|
||||
int Socket::Send(const void *buf, int amount)
|
||||
{
|
||||
if(SSLHandshake())
|
||||
return 0;
|
||||
return ssl ? ssl->Send(buf, amount) : RawSend(buf, amount);
|
||||
}
|
||||
|
||||
void TcpSocket::Shutdown()
|
||||
void Socket::Shutdown()
|
||||
{
|
||||
ASSERT(IsOpen());
|
||||
if(shutdown(socket, SD_SEND))
|
||||
SetSockError("shutdown(SD_SEND)");
|
||||
}
|
||||
|
||||
String TcpSocket::GetHostName()
|
||||
String Socket::GetHostName()
|
||||
{
|
||||
Init();
|
||||
char buffer[256];
|
||||
|
|
@ -596,7 +596,7 @@ String TcpSocket::GetHostName()
|
|||
return buffer;
|
||||
}
|
||||
|
||||
bool TcpSocket::IsGlobalTimeout()
|
||||
bool Socket::IsGlobalTimeout()
|
||||
{
|
||||
if(!IsNull(global_timeout) && msecs() - start_time > global_timeout) {
|
||||
SetSockError("wait", ERROR_GLOBAL_TIMEOUT, "Timeout");
|
||||
|
|
@ -605,7 +605,7 @@ bool TcpSocket::IsGlobalTimeout()
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TcpSocket::RawWait(dword flags, int end_time)
|
||||
bool Socket::RawWait(dword flags, int end_time)
|
||||
{ // wait till end_time
|
||||
LLOG("RawWait end_time: " << end_time << ", current time " << msecs() << ", to wait: " << end_time - msecs());
|
||||
is_timeout = false;
|
||||
|
|
@ -661,19 +661,19 @@ bool TcpSocket::RawWait(dword flags, int end_time)
|
|||
}
|
||||
}
|
||||
|
||||
TcpSocket& TcpSocket::GlobalTimeout(int ms)
|
||||
Socket& Socket::GlobalTimeout(int ms)
|
||||
{
|
||||
start_time = msecs();
|
||||
global_timeout = ms;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool TcpSocket::Wait(dword flags, int end_time)
|
||||
bool Socket::Wait(dword flags, int end_time)
|
||||
{
|
||||
return ssl ? ssl->Wait(flags, end_time) : RawWait(flags, end_time);
|
||||
}
|
||||
|
||||
int TcpSocket::GetEndTime() const
|
||||
int Socket::GetEndTime() const
|
||||
{ // Compute time limit for operation, based on global timeout and per-operation timeout settings
|
||||
int o = min(IsNull(global_timeout) ? INT_MAX : start_time + global_timeout,
|
||||
IsNull(timeout) ? INT_MAX : msecs() + timeout);
|
||||
|
|
@ -685,12 +685,12 @@ int TcpSocket::GetEndTime() const
|
|||
return o;
|
||||
}
|
||||
|
||||
bool TcpSocket::Wait(dword flags)
|
||||
bool Socket::Wait(dword flags)
|
||||
{
|
||||
return Wait(flags, GetEndTime());
|
||||
}
|
||||
|
||||
int TcpSocket::Put(const void *s_, int length)
|
||||
int Socket::Put(const void *s_, int length)
|
||||
{
|
||||
LLOG("Put " << socket << ": " << length);
|
||||
ASSERT(IsOpen());
|
||||
|
|
@ -718,7 +718,7 @@ int TcpSocket::Put(const void *s_, int length)
|
|||
return done;
|
||||
}
|
||||
|
||||
bool TcpSocket::PutAll(const void *s, int len)
|
||||
bool Socket::PutAll(const void *s, int len)
|
||||
{
|
||||
if(Put(s, len) != len) {
|
||||
if(!IsError())
|
||||
|
|
@ -728,7 +728,7 @@ bool TcpSocket::PutAll(const void *s, int len)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TcpSocket::PutAll(const String& s)
|
||||
bool Socket::PutAll(const String& s)
|
||||
{
|
||||
if(Put(s) != s.GetCount()) {
|
||||
if(!IsError())
|
||||
|
|
@ -738,7 +738,7 @@ bool TcpSocket::PutAll(const String& s)
|
|||
return true;
|
||||
}
|
||||
|
||||
int TcpSocket::RawRecv(void *buf, int amount)
|
||||
int Socket::RawRecv(void *buf, int amount)
|
||||
{
|
||||
int res = recv(socket, (char *)buf, amount, 0);
|
||||
if(res == 0)
|
||||
|
|
@ -755,26 +755,26 @@ int TcpSocket::RawRecv(void *buf, int amount)
|
|||
return res;
|
||||
}
|
||||
|
||||
int TcpSocket::Recv(void *buffer, int maxlen)
|
||||
int Socket::Recv(void *buffer, int maxlen)
|
||||
{
|
||||
if(SSLHandshake())
|
||||
return 0;
|
||||
return ssl ? ssl->Recv(buffer, maxlen) : RawRecv(buffer, maxlen);
|
||||
}
|
||||
|
||||
void TcpSocket::ReadBuffer(int end_time)
|
||||
void Socket::ReadBuffer(int end_time)
|
||||
{
|
||||
ptr = end = buffer;
|
||||
if(Wait(WAIT_READ, end_time))
|
||||
end = buffer + Recv(buffer, BUFFERSIZE);
|
||||
}
|
||||
|
||||
bool TcpSocket::IsEof() const
|
||||
bool Socket::IsEof() const
|
||||
{
|
||||
return is_eof && ptr == end || IsAbort() || !IsOpen() || IsError();
|
||||
}
|
||||
|
||||
int TcpSocket::Get_()
|
||||
int Socket::Get_()
|
||||
{
|
||||
if(!IsOpen() || IsError() || IsEof() || IsAbort())
|
||||
return -1;
|
||||
|
|
@ -782,7 +782,7 @@ int TcpSocket::Get_()
|
|||
return ptr < end ? (byte)*ptr++ : -1;
|
||||
}
|
||||
|
||||
int TcpSocket::Peek_(int end_time)
|
||||
int Socket::Peek_(int end_time)
|
||||
{
|
||||
if(!IsOpen() || IsError() || IsEof() || IsAbort())
|
||||
return -1;
|
||||
|
|
@ -790,12 +790,12 @@ int TcpSocket::Peek_(int end_time)
|
|||
return ptr < end ? (byte)*ptr : -1;
|
||||
}
|
||||
|
||||
int TcpSocket::Peek_()
|
||||
int Socket::Peek_()
|
||||
{
|
||||
return Peek_(GetEndTime());
|
||||
}
|
||||
|
||||
int TcpSocket::Get(void *buffer, int count)
|
||||
int Socket::Get(void *buffer, int count)
|
||||
{
|
||||
LLOG("Get " << count);
|
||||
|
||||
|
|
@ -829,7 +829,7 @@ int TcpSocket::Get(void *buffer, int count)
|
|||
return done;
|
||||
}
|
||||
|
||||
String TcpSocket::Get(int count)
|
||||
String Socket::Get(int count)
|
||||
{
|
||||
if(count == 0)
|
||||
return Null;
|
||||
|
|
@ -841,7 +841,7 @@ String TcpSocket::Get(int count)
|
|||
return String(out);
|
||||
}
|
||||
|
||||
bool TcpSocket::GetAll(void *buffer, int len)
|
||||
bool Socket::GetAll(void *buffer, int len)
|
||||
{
|
||||
if(Get(buffer, len) == len)
|
||||
return true;
|
||||
|
|
@ -850,7 +850,7 @@ bool TcpSocket::GetAll(void *buffer, int len)
|
|||
return false;
|
||||
}
|
||||
|
||||
String TcpSocket::GetAll(int len)
|
||||
String Socket::GetAll(int len)
|
||||
{
|
||||
String s = Get(len);
|
||||
if(s.GetCount() != len) {
|
||||
|
|
@ -861,7 +861,7 @@ String TcpSocket::GetAll(int len)
|
|||
return s;
|
||||
}
|
||||
|
||||
String TcpSocket::GetLine(int maxlen)
|
||||
String Socket::GetLine(int maxlen)
|
||||
{
|
||||
LLOG("GetLine " << maxlen << ", iseof " << IsEof());
|
||||
String ln;
|
||||
|
|
@ -892,7 +892,7 @@ String TcpSocket::GetLine(int maxlen)
|
|||
}
|
||||
}
|
||||
|
||||
void TcpSocket::SetSockError(const char *context, int code, const char *errdesc)
|
||||
void Socket::SetSockError(const char *context, int code, const char *errdesc)
|
||||
{
|
||||
errorcode = code;
|
||||
errordesc.Clear();
|
||||
|
|
@ -903,19 +903,19 @@ void TcpSocket::SetSockError(const char *context, int code, const char *errdesc)
|
|||
LLOG("ERROR " << errordesc);
|
||||
}
|
||||
|
||||
void TcpSocket::SetSockError(const char *context, const char *errdesc)
|
||||
void Socket::SetSockError(const char *context, const char *errdesc)
|
||||
{
|
||||
SetSockError(context, GetErrorCode(), errdesc);
|
||||
}
|
||||
|
||||
void TcpSocket::SetSockError(const char *context)
|
||||
void Socket::SetSockError(const char *context)
|
||||
{
|
||||
SetSockError(context, TcpSocketErrorDesc(GetErrorCode()));
|
||||
SetSockError(context, SocketErrorDesc(GetErrorCode()));
|
||||
}
|
||||
|
||||
TcpSocket::SSL *(*TcpSocket::CreateSSL)(TcpSocket& socket);
|
||||
Socket::SSL *(*Socket::CreateSSL)(Socket& socket);
|
||||
|
||||
bool TcpSocket::StartSSL()
|
||||
bool Socket::StartSSL()
|
||||
{
|
||||
ASSERT(IsOpen());
|
||||
if(!CreateSSL) {
|
||||
|
|
@ -940,7 +940,7 @@ bool TcpSocket::StartSSL()
|
|||
return true;
|
||||
}
|
||||
|
||||
dword TcpSocket::SSLHandshake()
|
||||
dword Socket::SSLHandshake()
|
||||
{
|
||||
if(ssl && (mode == CONNECT || mode == ACCEPT)) {
|
||||
dword w = ssl->Handshake();
|
||||
|
|
@ -958,25 +958,25 @@ dword TcpSocket::SSLHandshake()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void TcpSocket::SSLCertificate(const String& cert_, const String& pkey_, bool asn1_)
|
||||
void Socket::SSLCertificate(const String& cert_, const String& pkey_, bool asn1_)
|
||||
{
|
||||
cert = cert_;
|
||||
pkey = pkey_;
|
||||
asn1 = asn1_;
|
||||
}
|
||||
|
||||
void TcpSocket::SSLServerNameIndication(const String& name)
|
||||
void Socket::SSLServerNameIndication(const String& name)
|
||||
{
|
||||
sni = name;
|
||||
}
|
||||
|
||||
void TcpSocket::SSLCAcert(const String& cert, bool asn1_)
|
||||
void Socket::SSLCAcert(const String& cert, bool asn1_)
|
||||
{
|
||||
ca_cert = cert;
|
||||
asn1 = asn1_;
|
||||
}
|
||||
|
||||
void TcpSocket::Clear()
|
||||
void Socket::Clear()
|
||||
{
|
||||
ClearError();
|
||||
if(IsOpen())
|
||||
|
|
@ -984,6 +984,142 @@ void TcpSocket::Clear()
|
|||
Reset();
|
||||
}
|
||||
|
||||
#ifdef PLATFORM_POSIX
|
||||
|
||||
static bool sSetUnixSockType(Socket& s, const String& path, sockaddr_un& addr, bool abstract)
|
||||
{
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
|
||||
#ifndef PLATFORM_LINUX
|
||||
if(abstract) {
|
||||
s.SetSockError("SetUnixSockType",
|
||||
-1, "Abstract socket is not supported on this platform");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(abstract) {
|
||||
addr.sun_path[0] = '\0';
|
||||
if(path.GetLength() > 0) {
|
||||
ASSERT(path.GetLength() < sizeof(addr.sun_path) - 1);
|
||||
strncpy(addr.sun_path + 1, ~path, sizeof(addr.sun_path) - 2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(path.GetLength() > 0) {
|
||||
ASSERT(path.GetLength() < sizeof(addr.sun_path));
|
||||
strncpy(addr.sun_path, ~path, sizeof(addr.sun_path) - 1);
|
||||
addr.sun_path[sizeof(addr.sun_path) - 1] = '\0';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
s.SetSockError("SetUnixSockType",
|
||||
-1, "Failed to set unix domain socket type");
|
||||
return false;
|
||||
}
|
||||
|
||||
int Socket::GetPeerPid() const
|
||||
{
|
||||
if(!IsOpen())
|
||||
return -1;
|
||||
|
||||
#if defined(PLATFORM_LINUX)
|
||||
struct ucred ucred;
|
||||
socklen_t len = sizeof(ucred);
|
||||
if(getsockopt(socket, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == 0)
|
||||
return ucred.pid;
|
||||
|
||||
#elif (defined(PLATFORM_MACOS) || defined(PLATFORM_FREEBSD)) && defined(LOCAL_PEERPID)
|
||||
pid_t pid;
|
||||
socklen_t len = sizeof(pid);
|
||||
if(getsockopt(socket, SOL_LOCAL, LOCAL_PEERPID, &pid, &len) == 0)
|
||||
return pid;
|
||||
|
||||
#endif
|
||||
|
||||
return -1; // Not supported.
|
||||
}
|
||||
|
||||
bool Socket::NixConnect(const String& path, bool abstract)
|
||||
{
|
||||
Close();
|
||||
Init();
|
||||
Reset();
|
||||
|
||||
if(!Open(AF_UNIX, SOCK_STREAM, 0))
|
||||
return false;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
if(!sSetUnixSockType(*this, path, addr, abstract))
|
||||
return false;
|
||||
|
||||
if(connect(socket, (sockaddr *) &addr, sizeof(addr)) == 0 ||
|
||||
GetErrorCode() == EINPROGRESS || GetErrorCode() == EWOULDBLOCK) {
|
||||
mode = Socket::CONNECT;
|
||||
return true;
|
||||
}
|
||||
|
||||
SetSockError("connect", -1, strerror(GetErrorCode()));
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Socket::ConnectFileSystem(const String& path)
|
||||
{
|
||||
return NixConnect(path, false);
|
||||
}
|
||||
|
||||
bool Socket::ConnectAbstract(const String& path)
|
||||
{
|
||||
return NixConnect(path, true);
|
||||
}
|
||||
|
||||
bool Socket::NixListen(const String& path, int n, bool reuse, bool abstract)
|
||||
{
|
||||
Close();
|
||||
Init();
|
||||
Reset();
|
||||
|
||||
if(!Open(AF_UNIX, SOCK_STREAM, 0))
|
||||
return false;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
if(!sSetUnixSockType(*this, path, addr, abstract))
|
||||
return false;
|
||||
|
||||
if(reuse) {
|
||||
int optval = 1;
|
||||
setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char *) &optval, sizeof(optval));
|
||||
}
|
||||
|
||||
if(bind(socket, (const sockaddr *) &addr, sizeof(addr))) {
|
||||
SetSockError(Format("bind(path=%s)", path));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(listen(socket, n)) {
|
||||
SetSockError(Format("listen(path=%s, count=%d)", path, n));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Socket::ListenFileSystem(const String& path, int listen_count, bool reuse)
|
||||
{
|
||||
return NixListen(path, listen_count, reuse, false);
|
||||
}
|
||||
|
||||
bool Socket::ListenAbstract(const String& path, int listen_count, bool reuse)
|
||||
{
|
||||
return NixListen(path, listen_count, reuse, true);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int SocketWaitEvent::Wait(int timeout)
|
||||
{
|
||||
FD_ZERO(read);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
topic "SocketWaitEvent";
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
|
||||
[l288;2 $$2,2#27521748481378242620020725143825:desc]
|
||||
[0 $$3,0#96390100711032703541132217272105:end]
|
||||
|
|
@ -9,6 +8,7 @@ topic "SocketWaitEvent";
|
|||
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
|
||||
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
|
||||
[b42;2 $$9,9#13035079074754324216151401829390:normal]
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[{_}
|
||||
[ {{10000@(113.42.0) [s0;%% [*@7;4 SocketWaitEvent]]}}&]
|
||||
[s3; &]
|
||||
|
|
@ -28,9 +28,9 @@ sockets for specified events.&]
|
|||
Note that SocketWaitEvent always waits for exceptions.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:SocketWaitEvent`:`:Add`(TcpSocket`&`,dword`): [@(0.0.255) void]_[* Add]([_^TcpSocket^ T
|
||||
cpSocket][@(0.0.255) `&]_[*@3 s], [_^dword^ dword]_[*@3 events]_`=_WAIT`_ALL)&]
|
||||
[s2;%% Adds TcpSocket [%-*@3 s] to the list to be waited on specified
|
||||
[s5;:SocketWaitEvent`:`:Add`(Socket`&`,dword`): [@(0.0.255) void]_[* Add]([_^topic`:`/`/Core`/src`/Socket`_en`-us`#Socket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[*@3 s], [_^dword^ dword]_[*@3 events]_`=_WAIT`_ALL)&]
|
||||
[s2;%% Adds Socket [%-*@3 s] to the list to be waited on specified
|
||||
[%-*@3 events]. If [%-*@3 s] is not open, it is not used but its
|
||||
index is reserved anyway (see Get).&]
|
||||
[s3;%% &]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
topic "TcpSocket";
|
||||
topic "Socket";
|
||||
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
|
||||
[l288;2 $$2,2#27521748481378242620020725143825:desc]
|
||||
[0 $$3,0#96390100711032703541132217272105:end]
|
||||
|
|
@ -10,16 +10,16 @@ topic "TcpSocket";
|
|||
[b42;2 $$9,9#13035079074754324216151401829390:normal]
|
||||
[2 $$0,0#00000000000000000000000000000000:Default]
|
||||
[{_}
|
||||
[ {{10000@(113.42.0) [s0;%% [*@7;4 TcpSocket]]}}&]
|
||||
[ {{10000@(113.42.0) [s0;%% [*@7;4 Socket]]}}&]
|
||||
[s3; &]
|
||||
[s1;:TcpSocket`:`:class: [@(0.0.255)3 class][3 _][*3 TcpSocket]&]
|
||||
[s2;%% This class represents an TCP/IP socket. It extends the basic
|
||||
semantics of sockets to allow non`-blocking or time constrained
|
||||
operations.&]
|
||||
[s1;:Socket`:`:class: [@(0.0.255)3 class][3 _][*3 Socket]&]
|
||||
[s2;%% This class represents a TCP/IP socket or [^https`:`/`/en`.wikipedia`.org`/wiki`/Unix`_domain`_socket`?oldformat`=true^ U
|
||||
nix domain socket]. It extends the basic semantics of sockets
|
||||
to allow non`-blocking or time constrained operations.&]
|
||||
[s3; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
|
||||
[s3; &]
|
||||
[s5;:TcpSocket`:`:WhenWait: [_^topic`:`/`/Core`/src`/Callbacks`$en`-us`#Callback`:`:class^ C
|
||||
[s5;:Socket`:`:WhenWait: [_^topic`:`/`/Core`/src`/Callbacks`$en`-us`#Callback`:`:class^ C
|
||||
allback]_[* WhenWait]&]
|
||||
[s2;%% If this callback is defined, it is invoked periodically while
|
||||
TcpSocket performs any operations, with the period set by WaitStep
|
||||
|
|
@ -27,101 +27,133 @@ TcpSocket performs any operations, with the period set by WaitStep
|
|||
in interactive applications.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetHostName`(`): [@(0.0.255) static] [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:GetHostName`(`): [@(0.0.255) static] [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* GetHostName]()&]
|
||||
[s2;%% Returns the name of computer.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetDone`(`)const: [@(0.0.255) int]_[* GetDone]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:GetPeerPid`(`)const: [@(0.0.255) int] [* GetPeerPid]()
|
||||
[@(0.0.255) const]&]
|
||||
[s6; POSIX only&]
|
||||
[s2;%% Returns the process ID (pid) of the peer on success, `-1 on
|
||||
failure. On non`-blocking mode, make sure that socket is actually
|
||||
connected or accepted. This is only available on unix domain
|
||||
(local) sockets.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Socket`:`:GetDone`(`)const: [@(0.0.255) int]_[* GetDone]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns number of bytes processed during current operation;
|
||||
intended to be called from WhenWait routine&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:IsOpen`(`)const: [@(0.0.255) bool]_[* IsOpen]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:IsOpen`(`)const: [@(0.0.255) bool]_[* IsOpen]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if socket is open.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:IsEof`(`)const: [@(0.0.255) bool]_[* IsEof]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:IsEof`(`)const: [@(0.0.255) bool]_[* IsEof]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if there are no more input data to process. Also
|
||||
returns true if socket is not open, if there was an error or
|
||||
if socket was aborted.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:IsError`(`)const: [@(0.0.255) bool]_[* IsError]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:IsError`(`)const: [@(0.0.255) bool]_[* IsError]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if some previous operations reported error. In
|
||||
that case, all subsequent request are ignored.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:ClearError`(`): [@(0.0.255) void]_[* ClearError]()&]
|
||||
[s5;:Socket`:`:ClearError`(`): [@(0.0.255) void]_[* ClearError]()&]
|
||||
[s2;%% Clears the error state.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetError`(`)const: [@(0.0.255) int]_[* GetError]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:GetError`(`)const: [@(0.0.255) int]_[* GetError]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns errorcode. Errorcodes are either defined by SOCKET
|
||||
API or it can be `-1 for other errors.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetErrorDesc`(`)const: [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:GetErrorDesc`(`)const: [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* GetErrorDesc]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns description of error.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:Abort`(`): [@(0.0.255) void]_[* Abort]()&]
|
||||
[s2;%% Sets TcpSocket to aborted state. In aborted state, all subsequent
|
||||
[s5;:Socket`:`:Abort`(`): [@(0.0.255) void]_[* Abort]()&]
|
||||
[s2;%% Sets Socket to aborted state. In aborted state, all subsequent
|
||||
request are ignored. Intended to be called from WhenWait routine.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:IsAbort`(`)const: [@(0.0.255) bool]_[* IsAbort]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true is TcpSocket is in aborted state.&]
|
||||
[s5;:Socket`:`:IsAbort`(`)const: [@(0.0.255) bool]_[* IsAbort]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true is Socket is in aborted state.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:ClearAbort`(`): [@(0.0.255) void]_[* ClearAbort]()&]
|
||||
[s5;:Socket`:`:ClearAbort`(`): [@(0.0.255) void]_[* ClearAbort]()&]
|
||||
[s2;%% Clears the aborted state.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:IsTimeout`(`)const: [@(0.0.255) bool]_[* IsTimeout]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:IsTimeout`(`)const: [@(0.0.255) bool]_[* IsTimeout]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if the last operation time`-outed.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetSOCKET`(`)const: SOCKET_[* GetSOCKET]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns socket handle. Note that all TcpSocket sockets are
|
||||
non`-blocking from host OS perspective.&]
|
||||
[s5;:Socket`:`:GetSOCKET`(`)const: SOCKET_[* GetSOCKET]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns socket handle. Note that all Socket sockets are non`-blocking
|
||||
from host OS perspective.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetPeerAddr`(`)const: [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:GetPeerAddr`(`)const: [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* GetPeerAddr]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns the peer address.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:Attach`(SOCKET`): [@(0.0.255) void]_[* Attach](SOCKET_[*@3 socket])&]
|
||||
[s2;%% Attaches [%-*@3 socket] to TcpSocket. [%-*@3 socket] must be in
|
||||
non`-blocking state.&]
|
||||
[s5;:Socket`:`:Attach`(SOCKET`): [@(0.0.255) void]_[* Attach](SOCKET_[*@3 socket])&]
|
||||
[s2;%% Attaches [%-*@3 socket] to Socket. [%-*@3 socket] must be in non`-blocking
|
||||
state.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Connect`(const char`*`,int`): [@(0.0.255) bool]_[* Connect]([@(0.0.255) c
|
||||
onst]_[@(0.0.255) char]_`*[*@3 host], [@(0.0.255) int]_[*@3 port])&]
|
||||
[s5;:Socket`:`:Connect`(const char`*`,int`): [@(0.0.255) bool]_[* Connect]([@(0.0.255) cons
|
||||
t]_[@(0.0.255) char]_`*[*@3 host], [@(0.0.255) int]_[*@3 port])&]
|
||||
[s2;%% Connects socket to server at [%-*@3 host]:[%-*@3 port]. This operation
|
||||
is blocking with respect to resolving host name. Returns true
|
||||
when connection process is successfully started.&]
|
||||
[s3; &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Connect`(IpAddrInfo`&`): [@(0.0.255) bool]_[* Connect]([_^topic`:`/`/Core`/src`/IpAddrInfo`$en`-us`#IpAddrInfo`:`:class^ I
|
||||
[s5;:Socket`:`:Connect`(IpAddrInfo`&`): [@(0.0.255) bool]_[* Connect]([_^topic`:`/`/Core`/src`/IpAddrInfo`$en`-us`#IpAddrInfo`:`:class^ I
|
||||
pAddrInfo][@(0.0.255) `&]_[*@3 info])&]
|
||||
[s2;%% Connects socket to server found at [%-*@3 info]. Non`-blocking.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:WaitConnect`(`): [@(0.0.255) bool]_[* WaitConnect]()&]
|
||||
[s5;:Upp`:`:Socket`:`:ConnectFileSystem`(const String`&`): [@(0.0.255) bool]
|
||||
[* ConnectFileSystem]([@(0.0.255) const] String[@(0.0.255) `&] [*@3 path])&]
|
||||
[s6;%% POSIX only&]
|
||||
[s2;%% Connects socket to a Unix domain server bound at the given
|
||||
file system [%-*@3 path]. The path must exist on the file system.
|
||||
Returns true if connection is successful (blocking mode) or connection
|
||||
is in progress (non blocking mode). File system sockets are visible
|
||||
in the file system and require proper permissions. &]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:Socket`:`:ConnectAbstract`(const String`&`): [@(0.0.255) bool]
|
||||
[* ConnectAbstract]([@(0.0.255) const] String[@(0.0.255) `&] [*@3 path])&]
|
||||
[s6;%% Linux only&]
|
||||
[s2;%% Connects socket to a Unix domain server in the Linux abstract
|
||||
namespace. The [%-*@3 path ]is the name in the abstract namespace
|
||||
and does not correspond to a file system path. Returns true if
|
||||
connection is successful (blocking mode) or connection is in
|
||||
progress (non blocking mode). Abstract sockets exist only in
|
||||
kernel memory and disappear when processes exit. On non`-Linux
|
||||
POSIX systems, this function will fail and set the socket into
|
||||
error state. &]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Socket`:`:WaitConnect`(`): [@(0.0.255) bool]_[* WaitConnect]()&]
|
||||
[s2;%% After Connect returns true, WaitConnect waits for connection
|
||||
to be established. Note that it is only necessary to use WaitConnect
|
||||
if you want to intercept errors before sending/recieving data.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:Listen`(int`,int`,bool`,bool`,void`*`): [@(0.0.255) bool]_[* Listen]([@(0.0.255) i
|
||||
[s5;:Socket`:`:Listen`(int`,int`,bool`,bool`,void`*`): [@(0.0.255) bool]_[* Listen]([@(0.0.255) i
|
||||
nt]_[*@3 port], [@(0.0.255) int]_[*@3 listen`_count]_`=_[@3 5], [@(0.0.255) bool]_[*@3 ipv6]_
|
||||
`=_[@(0.0.255) false], [@(0.0.255) bool]_[*@3 reuse]_`=_[@(0.0.255) true],
|
||||
[@(0.0.255) void`*]_[*@3 addr]_`=_NULL)&]
|
||||
[s5;:TcpSocket`:`:Listen`(const IpAddrInfo`&`,int`,int`,bool`,bool`): [@(0.0.255) bool]_
|
||||
[* Listen]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/IpAddrInfo`$en`-us`#IpAddrInfo`:`:class^ I
|
||||
[s5;:Socket`:`:Listen`(const IpAddrInfo`&`,int`,int`,bool`,bool`): [@(0.0.255) bool]_[* L
|
||||
isten]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/IpAddrInfo`$en`-us`#IpAddrInfo`:`:class^ I
|
||||
pAddrInfo][@(0.0.255) `&]_[*@3 addr], [@(0.0.255) int]_[*@3 port], [@(0.0.255) int]_[*@3 list
|
||||
en`_count]_`=_[@3 5], [@(0.0.255) bool]_[*@3 ipv6]_`=_[@(0.0.255) false],
|
||||
[@(0.0.255) bool]_[*@3 reuse]_`=_[@(0.0.255) true])&]
|
||||
|
|
@ -135,34 +167,62 @@ to sockaddr`_in`::sin`_addr.s`_addr for ipv6`=`=true and/or in6`_addr
|
|||
to be dereferenced and assigned to sockaddr`_in6`::sin6`_addr
|
||||
for ipv6`=`=true.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:Socket`:`:ListenFileSystem`(const String`&`,int`,bool`): [@(0.0.255) bool]
|
||||
[* ListenFileSystem]([@(0.0.255) const ]String[@(0.0.255) `&] [*@3 path],
|
||||
[@(0.0.255) int] [*@3 listen`_count] [@(0.0.255) `=] [@3 5], [@(0.0.255) bool]
|
||||
[*@3 reuse] [@(0.0.255) `=] [@(0.0.255) true])&]
|
||||
[s6; POSIX only&]
|
||||
[s2;%% Creates a Unix domain server socket bound to the given file
|
||||
system [%-*@3 path]. [%-*@3 listen`_count] specifies the maximum
|
||||
number of pending connections in the queue. [%-*@3 reuse] indicates
|
||||
whether the socket should allow reuse of the address if it already
|
||||
exists. returns true if the listen is successful.&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:Socket`:`:ListenAbstract`(const String`&`,int`,bool`): [@(0.0.255) bool]
|
||||
[* ListenAbstract]([@(0.0.255) const] String[@(0.0.255) `&] [*@3 path],
|
||||
[@(0.0.255) int] [*@3 listen`_count] [@(0.0.255) `=] [@3 5], [@(0.0.255) bool]
|
||||
[*@3 reuse] [@(0.0.255) `=] [@(0.0.255) true])&]
|
||||
[s6; Linux only&]
|
||||
[s2;%% Creates a Unix domain server socket in the Linux abstract
|
||||
namespace. [%-*@3 path] is the name in the abstract namespace (does
|
||||
not correspond to a file system path). [%-*@3 listen`_count] specifies
|
||||
the maximum number of pending connections. [%-*@3 reuse] indicates
|
||||
whether the abstract socket name can be reused. Abstract sockets
|
||||
exist only in kernel memory and disappear when processes exit.
|
||||
On non`-Linux POSIX systems, this method will fail and set the
|
||||
socket into error state.&]
|
||||
[s3; &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Accept`(TcpSocket`&`): [@(0.0.255) bool]_[* Accept]([_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T
|
||||
cpSocket][@(0.0.255) `&]_[*@3 listen`_socket])&]
|
||||
[s5;:Socket`:`:Accept`(Socket`&`): [@(0.0.255) bool]_[* Accept]([_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[*@3 listen`_socket])&]
|
||||
[s2;%% Accepts a connection from [%-*@3 listen`_socket].&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Close`(`): [@(0.0.255) void]_[* Close]()&]
|
||||
[s5;:Socket`:`:Close`(`): [@(0.0.255) void]_[* Close]()&]
|
||||
[s2;%% Closes the socket.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Shutdown`(`): [@(0.0.255) void]_[* Shutdown]()&]
|
||||
[s5;:Socket`:`:Shutdown`(`): [@(0.0.255) void]_[* Shutdown]()&]
|
||||
[s2;%% Performs shutdown for write operations. Normally not needed.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:NoDelay`(`): [@(0.0.255) void]_[* NoDelay]()&]
|
||||
[s2;%% Sets TCP`_NODELAY option.&]
|
||||
[s5;:Socket`:`:NoDelay`(`): [@(0.0.255) void]_[* NoDelay]()&]
|
||||
[s2;%% Sets TCP`_NODELAY option. Note that this option is not available
|
||||
for unix domain sockets.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Linger`(int`): [@(0.0.255) void]_[* Linger]([@(0.0.255) int]_[*@3 msecs])&]
|
||||
[s5;:Socket`:`:Linger`(int`): [@(0.0.255) void]_[* Linger]([@(0.0.255) int]_[*@3 msecs])&]
|
||||
[s2;%% Sets SO`_LINGER option to [%-*@3 msecs]. If [%-*@3 msecs] is Null,
|
||||
switches SO`_LINGER off.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:NoLinger`(`): [@(0.0.255) void]_[* NoLinger]()&]
|
||||
[s5;:Socket`:`:NoLinger`(`): [@(0.0.255) void]_[* NoLinger]()&]
|
||||
[s2;%% Same as Linger(Null).&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Wait`(dword`): [@(0.0.255) bool]_[* Wait]([_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:dword`:`:typedef^ d
|
||||
[s5;:Socket`:`:Wait`(dword`): [@(0.0.255) bool]_[* Wait]([_^topic`:`/`/Core`/src`/PrimitiveDataTypes`$en`-us`#Upp`:`:dword`:`:typedef^ d
|
||||
word]_[*@3 events])&]
|
||||
[s2;%% Waits for at most timeout for [%-*@3 events], which can be a
|
||||
combination of WAIT`_READ (wait for more input bytes available),
|
||||
|
|
@ -172,100 +232,99 @@ true if wait was successful (data can be written/read after the
|
|||
wait), false on timeout.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:WaitRead`(`): [@(0.0.255) bool]_[* WaitRead]()&]
|
||||
[s5;:Socket`:`:WaitRead`(`): [@(0.0.255) bool]_[* WaitRead]()&]
|
||||
[s2;%% Same as Wait(WAIT`_READ).&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:WaitWrite`(`): [@(0.0.255) bool]_[* WaitWrite]()&]
|
||||
[s5;:Socket`:`:WaitWrite`(`): [@(0.0.255) bool]_[* WaitWrite]()&]
|
||||
[s2;%% Same as Wait(WAIT`_WRITE).&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Peek`(`): [@(0.0.255) int]_[* Peek]()&]
|
||||
[s5;:TcpSocket`:`:Term`(`): [@(0.0.255) int]_[* Term]()&]
|
||||
[s5;:Socket`:`:Peek`(`): [@(0.0.255) int]_[* Peek]()&]
|
||||
[s5;:Socket`:`:Term`(`): [@(0.0.255) int]_[* Term]()&]
|
||||
[s2;%% Returns the next input byte without actually removing it from
|
||||
input queue. It at most waits for specified timeout for it, if
|
||||
there is still none, returns `-1.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Get`(`): [@(0.0.255) int]_[* Get]()&]
|
||||
[s5;:Socket`:`:Get`(`): [@(0.0.255) int]_[* Get]()&]
|
||||
[s2;%% Reads the next input byte. It at most waits for specified
|
||||
timeout for it, if there is still none, returns `-1.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Get`(void`*`,int`): [@(0.0.255) int]_[* Get]([@(0.0.255) void]_`*[*@3 buffe
|
||||
r], [@(0.0.255) int]_[*@3 len])&]
|
||||
[s5;:Socket`:`:Get`(void`*`,int`): [@(0.0.255) int]_[* Get]([@(0.0.255) void]_`*[*@3 buffer],
|
||||
[@(0.0.255) int]_[*@3 len])&]
|
||||
[s2;%% Reads at most [%-*@3 len] bytes into [%-*@3 buffer], trying to
|
||||
do so at most for specified timeout. Returns the number of bytes
|
||||
actually read.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Get`(int`): [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* Get]([@(0.0.255) int]_[*@3 len])&]
|
||||
[s5;:Socket`:`:Get`(int`): [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ St
|
||||
ring]_[* Get]([@(0.0.255) int]_[*@3 len])&]
|
||||
[s2;%% Reads at most [%-*@3 len] bytes, trying to do so at most for
|
||||
specified timeout. Returns a String with read data.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:Put`(const void`*`,int`): [@(0.0.255) int]_[* Put]([@(0.0.255) const]_[@(0.0.255) v
|
||||
[s5;:Socket`:`:Put`(const void`*`,int`): [@(0.0.255) int]_[* Put]([@(0.0.255) const]_[@(0.0.255) v
|
||||
oid]_`*[*@3 s], [@(0.0.255) int]_[*@3 len])&]
|
||||
[s2;%% Writes at most [%-*@3 len] bytes from [%-*@3 buffer], trying to
|
||||
do so at most for specified timeout. Returns the number of bytes
|
||||
actually written.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Put`(const String`&`): [@(0.0.255) int]_[* Put]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:Put`(const String`&`): [@(0.0.255) int]_[* Put]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring][@(0.0.255) `&]_[*@3 s])&]
|
||||
[s2;%% Writes [%-*@3 s], trying to do so at most for specified timeout.
|
||||
Returns the number of bytes actually written.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:GetAll`(void`*`,int`): [@(0.0.255) bool]_[* GetAll]([@(0.0.255) void]_`*[*@3 b
|
||||
[s5;:Socket`:`:GetAll`(void`*`,int`): [@(0.0.255) bool]_[* GetAll]([@(0.0.255) void]_`*[*@3 b
|
||||
uffer], [@(0.0.255) int]_[*@3 len])&]
|
||||
[s2;%% Reads exactly [%-*@3 len] bytes into [%-*@3 buffer]. If such number
|
||||
of bytes cannot be read until timeout, returns false and sets
|
||||
timeout error for TcpSocket.&]
|
||||
timeout error for Socket.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:GetAll`(int`): [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:GetAll`(int`): [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* GetAll]([@(0.0.255) int]_[*@3 len])&]
|
||||
[s2;%% Reads exactly [%-*@3 len] bytes. If such number of bytes cannot
|
||||
be read until timeout, returns String`::GetVoid() and sets timeout
|
||||
error for TcpSocket.&]
|
||||
error for Socket.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:GetLine`(int`): [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:GetLine`(int`): [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* GetLine]([@(0.0.255) int]_[*@3 maxlen]_`=_[@3 65536])&]
|
||||
[s2;%% Reads single line (ended with `'`\n`', `'`\r`' is ignored).
|
||||
If the whole line cannot be read within timeout or line length
|
||||
is longer than [%-*@3 maxlen] sets error and returns String`::GetVoid().&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:PutAll`(const void`*`,int`): [@(0.0.255) bool]_[* PutAll]([@(0.0.255) con
|
||||
st]_[@(0.0.255) void]_`*[*@3 s], [@(0.0.255) int]_[*@3 len])&]
|
||||
[s5;:Socket`:`:PutAll`(const void`*`,int`): [@(0.0.255) bool]_[* PutAll]([@(0.0.255) const]_
|
||||
[@(0.0.255) void]_`*[*@3 s], [@(0.0.255) int]_[*@3 len])&]
|
||||
[s2;%% Outputs exactly [%-*@3 len] bytes. If such number of bytes cannot
|
||||
be written in time specified by timeout, sets error and returns
|
||||
false.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:PutAll`(const String`&`): [@(0.0.255) bool]_[* PutAll]([@(0.0.255) const]_
|
||||
[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ String][@(0.0.255) `&]_[*@3 s
|
||||
])&]
|
||||
[s5;:Socket`:`:PutAll`(const String`&`): [@(0.0.255) bool]_[* PutAll]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring][@(0.0.255) `&]_[*@3 s])&]
|
||||
[s2;%% Outputs the whole String. If such number of bytes cannot be
|
||||
written in time specified by timeout, sets error and returns
|
||||
false.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:StartSSL`(`): [@(0.0.255) bool]_[* StartSSL]()&]
|
||||
[s2;%% Sets TcpSocket to SSL mode and starts SSL handshake. Core/SSL
|
||||
[s5;:Socket`:`:StartSSL`(`): [@(0.0.255) bool]_[* StartSSL]()&]
|
||||
[s2;%% Sets Socket to SSL mode and starts SSL handshake. Core/SSL
|
||||
must be present in project. Returns true if SSL could have been
|
||||
started. Handshake is not finished until SSLHandshake returns
|
||||
false.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:IsSSL`(`)const: [@(0.0.255) bool]_[* IsSSL]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if TcpSocket is in SSL mode.&]
|
||||
[s5;:Socket`:`:IsSSL`(`)const: [@(0.0.255) bool]_[* IsSSL]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns true if Socket is in SSL mode.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:SSLHandshake`(`): [@(0.0.255) dword]_[* SSLHandshake]()&]
|
||||
[s5;:Socket`:`:SSLHandshake`(`): [@(0.0.255) dword]_[* SSLHandshake]()&]
|
||||
[s2;%% Attempts the progress on SSL handshake for at most timeout
|
||||
period. Returns a combination of WAIT`_READ and WAIT`_WRITE if
|
||||
SSL handshake is (still) in progress, indicating whether the
|
||||
|
|
@ -273,8 +332,8 @@ process needs to read or write more bytes from the socket. Returns
|
|||
0 if handshake is finished.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:SSLCertificate`(const String`&`,const String`&`,bool`): [@(0.0.255) v
|
||||
oid]_[* SSLCertificate]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
[s5;:Socket`:`:SSLCertificate`(const String`&`,const String`&`,bool`): [@(0.0.255) void
|
||||
]_[* SSLCertificate]([@(0.0.255) const]_[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring][@(0.0.255) `&]_[*@3 cert], [@(0.0.255) const]_[_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring][@(0.0.255) `&]_[*@3 pkey], [@(0.0.255) bool]_[*@3 asn1])&]
|
||||
[s2;%% Sets the SSL certificate. Must be called before StartSSL.
|
||||
|
|
@ -282,37 +341,37 @@ tring][@(0.0.255) `&]_[*@3 pkey], [@(0.0.255) bool]_[*@3 asn1])&]
|
|||
usually used on accepting sockets.)&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:TcpSocket`:`:SSLServerNameIndication`(const Upp`:`:String`&`): [@(0.0.255) v
|
||||
oid]_[* SSLServerNameIndication]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&
|
||||
]_[*@3 name])&]
|
||||
[s5;:Socket`:`:SSLServerNameIndication`(const Upp`:`:String`&`): [@(0.0.255) void]_[* SSL
|
||||
ServerNameIndication]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 na
|
||||
me])&]
|
||||
[s2;%% Sets [^https`:`/`/cs`.wikipedia`.org`/wiki`/Server`_Name`_Indication^ SNI]
|
||||
for SSL connection.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:GetSSLInfo`(`)const: [@(0.0.255) const]_[_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#SSLInfo`:`:struct^ S
|
||||
[s5;:Socket`:`:GetSSLInfo`(`)const: [@(0.0.255) const]_[_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#SSLInfo`:`:struct^ S
|
||||
SLInfo]_`*[* GetSSLInfo]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns information about established (after handshake) SSL
|
||||
connection or NULL if such information is not available.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Timeout`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T
|
||||
cpSocket][@(0.0.255) `&]_[* Timeout]([@(0.0.255) int]_[*@3 ms])&]
|
||||
[s5;:Socket`:`:Timeout`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[* Timeout]([@(0.0.255) int]_[*@3 ms])&]
|
||||
[s2;%% Sets timeout for all operations. Zero means that all operations
|
||||
return immediately (in that case it is usually a good idea to
|
||||
perform some sort of external blocking on socket or socket group
|
||||
using e.g. SocketWaitEvent). Null means operations are blocking
|
||||
(but they still can invoke WhenProgress periodically if defined).
|
||||
Other values specify a number of milliseconds. Note: It is possible
|
||||
to adjust timeout before any single TcpSocket operation. Returns
|
||||
`*this. Default value is Null, which means TcpSocket is blocking.&]
|
||||
to adjust timeout before any single Socket operation. Returns
|
||||
`*this. Default value is Null, which means Socket is blocking.&]
|
||||
[s3;%% &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:GetTimeout`(`)const: [@(0.0.255) int]_[* GetTimeout]()_[@(0.0.255) const]&]
|
||||
[s5;:Socket`:`:GetTimeout`(`)const: [@(0.0.255) int]_[* GetTimeout]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns current timeout.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GlobalTimeout`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T
|
||||
cpSocket][@(0.0.255) `&]_[* GlobalTimeout]([@(0.0.255) int]_[*@3 ms])&]
|
||||
[s5;:Socket`:`:GlobalTimeout`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[* GlobalTimeout]([@(0.0.255) int]_[*@3 ms])&]
|
||||
[s2;%% Sets the `"global timeout`". This timeout is in effect over
|
||||
a whole range of operations, until it is canceled by calling
|
||||
this method with Null parameter or by setting a new global timeout.
|
||||
|
|
@ -320,34 +379,33 @@ If global timeout is exceeded, operation during which it happened
|
|||
fails and socket error code is set to ERROR`_GLOBAL`_TIMEOUT.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:NoGlobalTimeout`(`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T
|
||||
cpSocket][@(0.0.255) `&]_[* NoGlobalTimeout]()&]
|
||||
[s5;:Socket`:`:NoGlobalTimeout`(`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[* NoGlobalTimeout]()&]
|
||||
[s2;%% Same as GlobalTimeout(Null).&]
|
||||
[s3; &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:Blocking`(`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T
|
||||
cpSocket][@(0.0.255) `&]_[* Blocking]()&]
|
||||
[s5;:Socket`:`:Blocking`(`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[* Blocking]()&]
|
||||
[s2;%% Same as Timeout(Null). Returns `*this. This is the default
|
||||
value.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:Upp`:`:TcpSocket`:`:IsBlocking`(`): [@(0.0.255) bool]_[* IsBlocking]()&]
|
||||
[s5;:Socket`:`:IsBlocking`(`): [@(0.0.255) bool]_[* IsBlocking]()&]
|
||||
[s2;%% Same is IsNull(GetTimeout()).&]
|
||||
[s3; &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:WaitStep`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ T
|
||||
cpSocket][@(0.0.255) `&]_[* WaitStep]([@(0.0.255) int]_[*@3 ms])&]
|
||||
[s5;:Socket`:`:WaitStep`(int`): [_^topic`:`/`/Core`/src`/TcpSocket`$en`-us`#TcpSocket`:`:class^ S
|
||||
ocket][@(0.0.255) `&]_[* WaitStep]([@(0.0.255) int]_[*@3 ms])&]
|
||||
[s2;%% Sets the periodicity of calling WhenWait in millisecond between
|
||||
calls. Default is 10ms (100hz).&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:TcpSocket`:`:GetWaitStep`(`)const: [@(0.0.255) int]_[* GetWaitStep]()_[@(0.0.255) cons
|
||||
t]&]
|
||||
[s2;%% Retruns current periodicity of calling WhenWait.&]
|
||||
[s5;:Socket`:`:GetWaitStep`(`)const: [@(0.0.255) int]_[* GetWaitStep]()_[@(0.0.255) const]&]
|
||||
[s2;%% Returns current periodicity of calling WhenWait.&]
|
||||
[s3; &]
|
||||
[s4;%% &]
|
||||
[s5;:TcpSocket`:`:TcpSocket`(`): [* TcpSocket]()&]
|
||||
[s5;:TcpSocket`:`:`~TcpSocket`(`): [@(0.0.255) `~][* TcpSocket]()&]
|
||||
[s5;:Socket`:`:Socket`(`): [* Socket]()&]
|
||||
[s5;:Socket`:`:`~Socket`(`): [@(0.0.255) `~][* Socket]()&]
|
||||
[s2;%% Constructor, destructor.&]
|
||||
[s3;%% &]
|
||||
[s0; &]
|
||||
|
|
@ -394,4 +452,4 @@ ate]_[* cert`_notafter]&]
|
|||
[s5;:SSLInfo`:`:cert`_serial: [_^topic`:`/`/Core`/src`/String`$en`-us`#String`:`:class^ S
|
||||
tring]_[* cert`_serial]&]
|
||||
[s2;%% Serial number of certificate.&]
|
||||
[s3; ]]
|
||||
[s0;%% ]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue