如何在 D 中使用 Unix 域套接字进行 IPC?
How to do IPC using Unix Domain Socket in D?
这里我有一个程序想要
检测是否是唯一实例
1.1。它通过尝试创建一个 Unix Domain Socket 来做到这一点
并尝试将其绑定到特定地址。
如果重复程序不是运行,建立一个UDS
然后听套接字。
2.1。如果有任何消息通过该套接字,程序将记录传入的消息
2.2。否则它应该永远监听套接字
如果有重复的程序,它应该发送一条消息然后退出。
这是我拥有的:
import std.socket, std.experimental.logger;
immutable string socketAddress = "[=10=]/tmp/com.localserver.myapp";
void main()
{
auto socket = new std.socket.Socket(std.socket.AddressFamily.UNIX,
std.socket.SocketType.STREAM);
auto addr = new std.socket.UnixAddress(socketAddress);
auto isUnique = () {
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(addr);
result = true;
}
catch (std.socket.SocketOSException e)
result = false;
// else throw error
return result;
}();
if (isUnique)
{
log("Unique instance detected. Listening...");
// works upto now
char[] buffer = [];
while (1)
{
socket.listen(0);
socket.receive(buffer);
if (buffer != []) {
log("Received message: ", buffer);
}
buffer = [];
}
}
else
{
log("Duplicate instance detected.");
socket.connect(addr);
import std.stdio;
stdout.write("Enter your message:\t");
socket.send(readln());
log("Message has been sent. Exiting.");
}
}
文档对于没有socket编程经验的人来说似乎不是很友好。如何使用 std.socket.Socket 发送和接收消息?
绑定后,其实还需要accept
。它将 return 一个新的 Socket 实例,您实际上可以从中 receive
。您的客户端分支看起来不错。我认为这是你的主要错误。
我的书中也有一个代码示例,它显示了 std.socket 的基本功能,可以作为示例提供帮助:
http://arsdnet.net/dcode/book/chapter_02/03/
它是 tcp,但使其成为 unix 就意味着改变系列,就像您在代码中所做的那样。
您还可以查找 C 等的套接字教程,D 套接字只是那些相同 BSD 风格套接字函数的薄包装。
正如 Adam 指出的那样,我首先使用了 listen()
方法,然后应用 accept()
方法,其中 returns 一个可以接收消息的套接字。然后接收器套接字占用 char[N]
缓冲区。
import std.socket, std.experimental.logger;
class UDSIPC
{
private:
static immutable string socketAddress = "[=10=]/tmp/com.localserver.myapp";
static immutable size_t messageBufferSize = 64;
static immutable string socketAddressName = "[=10=]/tmp/com.localserver.myapp";
Socket socket;
UnixAddress uaddr;
public:
this(in string socketAddressName = socketAddressName)
{
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
uaddr = new UnixAddress(socketAddress);
}
bool getUniqueness()
{
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(uaddr);
result = true;
}
catch (SocketOSException e)
result = false;
// else throw error
return result;
}
string getMessage()
{
socket.listen(0);
auto receiverSocket = socket.accept();
char[messageBufferSize] buffer;
auto amount = receiverSocket.receive(buffer);
import std.string;
return format!"%s"(buffer[0 .. amount]);
}
void sendMessage(in string message)
{
socket.connect(uaddr);
socket.send(message);
}
}
void main()
{
auto ipc = new UDSIPC();
if (ipc.getUniqueness())
{
while (true)
{
log(ipc.getMessage());
}
}
else
{
import std.stdio, std.string;
ipc.sendMessage(readln().chomp());
}
}
这里我有一个程序想要
检测是否是唯一实例
1.1。它通过尝试创建一个 Unix Domain Socket 来做到这一点 并尝试将其绑定到特定地址。
如果重复程序不是运行,建立一个UDS 然后听套接字。
2.1。如果有任何消息通过该套接字,程序将记录传入的消息
2.2。否则它应该永远监听套接字
如果有重复的程序,它应该发送一条消息然后退出。
这是我拥有的:
import std.socket, std.experimental.logger;
immutable string socketAddress = "[=10=]/tmp/com.localserver.myapp";
void main()
{
auto socket = new std.socket.Socket(std.socket.AddressFamily.UNIX,
std.socket.SocketType.STREAM);
auto addr = new std.socket.UnixAddress(socketAddress);
auto isUnique = () {
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(addr);
result = true;
}
catch (std.socket.SocketOSException e)
result = false;
// else throw error
return result;
}();
if (isUnique)
{
log("Unique instance detected. Listening...");
// works upto now
char[] buffer = [];
while (1)
{
socket.listen(0);
socket.receive(buffer);
if (buffer != []) {
log("Received message: ", buffer);
}
buffer = [];
}
}
else
{
log("Duplicate instance detected.");
socket.connect(addr);
import std.stdio;
stdout.write("Enter your message:\t");
socket.send(readln());
log("Message has been sent. Exiting.");
}
}
文档对于没有socket编程经验的人来说似乎不是很友好。如何使用 std.socket.Socket 发送和接收消息?
绑定后,其实还需要accept
。它将 return 一个新的 Socket 实例,您实际上可以从中 receive
。您的客户端分支看起来不错。我认为这是你的主要错误。
我的书中也有一个代码示例,它显示了 std.socket 的基本功能,可以作为示例提供帮助: http://arsdnet.net/dcode/book/chapter_02/03/
它是 tcp,但使其成为 unix 就意味着改变系列,就像您在代码中所做的那样。
您还可以查找 C 等的套接字教程,D 套接字只是那些相同 BSD 风格套接字函数的薄包装。
正如 Adam 指出的那样,我首先使用了 listen()
方法,然后应用 accept()
方法,其中 returns 一个可以接收消息的套接字。然后接收器套接字占用 char[N]
缓冲区。
import std.socket, std.experimental.logger;
class UDSIPC
{
private:
static immutable string socketAddress = "[=10=]/tmp/com.localserver.myapp";
static immutable size_t messageBufferSize = 64;
static immutable string socketAddressName = "[=10=]/tmp/com.localserver.myapp";
Socket socket;
UnixAddress uaddr;
public:
this(in string socketAddressName = socketAddressName)
{
socket = new Socket(AddressFamily.UNIX, SocketType.STREAM);
uaddr = new UnixAddress(socketAddress);
}
bool getUniqueness()
{
bool result;
scope (success)
log("returns: ", result);
try
{
socket.bind(uaddr);
result = true;
}
catch (SocketOSException e)
result = false;
// else throw error
return result;
}
string getMessage()
{
socket.listen(0);
auto receiverSocket = socket.accept();
char[messageBufferSize] buffer;
auto amount = receiverSocket.receive(buffer);
import std.string;
return format!"%s"(buffer[0 .. amount]);
}
void sendMessage(in string message)
{
socket.connect(uaddr);
socket.send(message);
}
}
void main()
{
auto ipc = new UDSIPC();
if (ipc.getUniqueness())
{
while (true)
{
log(ipc.getMessage());
}
}
else
{
import std.stdio, std.string;
ipc.sendMessage(readln().chomp());
}
}