我如何编写一个简单的 - 最简单的工作 - 测试应用程序,说明如何使用IPC /命名管道?
例如,如何编写一个控制台应用程序,程序1将"Hello World"写入程序2,程序2接收消息并将"Roger That"回复给程序1.
每个人似乎都说命名管道比插座IPC快.他们快多快了?我更喜欢使用套接字,因为它们可以进行双向通信并且非常灵活,但如果数量相当大,则会选择速度而不是灵活性.
我正在寻找WCF命名管道的最小示例(我期望两个最小的应用程序,服务器和客户端,它们可以通过命名管道进行通信.)
Microsoft有一篇很好的文章" 入门教程",它通过HTTP描述了WCF,我正在寻找类似于WCF和命名管道的东西.
我在互联网上发现了几个帖子,但它们有点"先进".我需要一些最小的,只有强制性的功能,所以我可以添加我的代码并使应用程序正常工作.
如何替换它以使用命名管道?
<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator" name="WSHttpBinding_ICalculator">
<identity>
<userPrincipalName value="OlegPc\Oleg" />
</identity>
</endpoint>
Run Code Online (Sandbox Code Playgroud)
如何替换它以使用命名管道?
// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");
// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);
try
{
// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");
// Step 4 of the hosting …
Run Code Online (Sandbox Code Playgroud) 在使用Python在各种UNIX(Linux,FreeBSD和MacOS X)下处理命名管道(FIFO)时,我注意到了一些奇怪的事情.第一个,也许是最烦人的是尝试打开空闲/空闲FIFO只读将被阻止(除非我使用os.O_NONBLOCK
较低级别的os.open()
调用).但是,如果我打开它进行读/写,那么我就不会阻塞.
例子:
f = open('./myfifo', 'r') # Blocks unless data is already in the pipe
f = os.open('./myfifo', os.O_RDONLY) # ditto
# Contrast to:
f = open('./myfifo', 'w+') # does NOT block
f = os.open('./myfifo', os.O_RDWR) # ditto
f = os.open('./myfifo', os.O_RDONLY|os.O_NONBLOCK) # ditto
Run Code Online (Sandbox Code Playgroud)
我只是好奇为什么.为什么打开调用块而不是后续的一些读操作?
另外我注意到非阻塞文件描述符可以表现为Python中的不同行为.在我使用的情况下os.open()
与os.O_NONBLOCK
初始开启操作那么os.read()
似乎如果数据还没有准备好文件描述符返回一个空字符串.但是,如果我使用fcntl.fcnt(f.fileno(), fcntl.F_SETFL, fcntl.GETFL | os.O_NONBLOCK)
然后os.read
引发异常(errno.EWOULDBLOCK
)
是否有一些其他标志open()
由我的os.open()
例子未设置的法线设置?它们有什么不同,为什么?
有人可以澄清PipeTransmissionMode.Message
.NET中的含义吗?
.NET如何区分通过管道传递的一条消息?
BinaryFormatter
,然后将其作为消息传递给管道吗?PipeTransmissionMode.Message
模式时允许的字符串消息?我启动了我的应用程序,它生成了许多Threads,每个Threads创建一个NamedPipeServer(.net 3.5为Named Pipe IPC添加了托管类型)并等待客户端连接(Blocks).代码按预期运行.
private void StartNamedPipeServer()
{
using (NamedPipeServerStream pipeStream =
new NamedPipeServerStream(m_sPipeName, PipeDirection.InOut, m_iMaxInstancesToCreate, PipeTransmissionMode.Message, PipeOptions.None))
{
m_pipeServers.Add(pipeStream);
while (!m_bShutdownRequested)
{
pipeStream.WaitForConnection();
Console.WriteLine("Client connection received by {0}", Thread.CurrentThread.Name);
....
Run Code Online (Sandbox Code Playgroud)
现在我还需要一种Shutdown方法来干净地完成这个过程.我尝试了通常的bool标志isShutdownRequested技巧.但是管道流在WaitForConnection()调用中保持阻塞,并且线程不会死亡.
public void Stop()
{
m_bShutdownRequested = true;
for (int i = 0; i < m_iMaxInstancesToCreate; i++)
{
Thread t = m_serverThreads[i];
NamedPipeServerStream pipeStream = m_pipeServers[i];
if (pipeStream != null)
{
if (pipeStream.IsConnected)
pipeStream.Disconnect();
pipeStream.Close();
pipeStream.Dispose();
}
Console.Write("Shutting down {0} ...", t.Name);
t.Join();
Console.WriteLine(" done!");
}
}
Run Code Online (Sandbox Code Playgroud)
加入永不回归.
我没有尝试但可能会工作的选项是调用Thread.Abort并吃掉异常.但它感觉不对..任何建议 …
我正在开发一个TCP代理,它将放在TCP服务之前,该服务应该处理来自通配Internet的500到1000个活动连接.
代理与服务在同一台机器上运行,并且大部分都是透明的.该服务在很大程度上不知道代理,唯一的例外是通知客户端的真实远程IP地址.
这意味着,对于每个入站打开的TCP套接字,服务器上还有两个套接字:代理中的第二个套接字,以及代理后面的真实服务上的套接字.
两个代理套接字上的send和recv窗口大小设置为1024字节.
对此有何影响?这个配置有多慢?我是否应该努力改变服务以使用命名管道(或其他IPC机制),或者localhost TCP套接字在很大程度上是一个有效的IPC?
这两个应用程序的合并不是一种选择.现在我们坚持使用两个流程配置.
编辑:在同一硬件上进行两个独立过程的原因是100%经济性.我们只有一台服务器,我们不打算获得更多(没有钱).
TCP服务是Visual Basic 6中的遗留软件,它超出了我们的预期.代理是C++.我们没有时间,金钱和人力来重写和迁移VB6代码到现代编程环境.
代理是我们尝试缓解服务的特定性能问题,这是我们不时会遇到的DDoS攻击.
代理是开源的,这是项目源代码.
根据这篇文章,带有命名管道的WCF是IPC的最佳选择,它比.Net Remoting快25%左右.
我有以下代码将WCF与命名管道与.Net Remoting进行比较:
[ServiceContract]
internal interface IRemote
{
[OperationContract]
string Hello(string name);
}
[ServiceBehavior]
internal class Remote : MarshalByRefObject, IRemote
{
public string Hello(string name)
{
return string.Format("Hello, {0}!", name);
}
}
class Program
{
private const int Iterations = 5000;
static void Main(string[] args)
{
TestWcf(Iterations);
TestRemoting(Iterations);
TestWcf(Iterations);
TestRemoting(Iterations);
TestWcf(Iterations);
TestRemoting(Iterations);
Console.ReadKey();
}
private static void TestRemoting(int iterations)
{
var domain = AppDomain.CreateDomain("TestDomain");
var proxy =
(IRemote)
domain.CreateInstanceFromAndUnwrap(Assembly.GetEntryAssembly().Location, "ConsoleApplication6.Remote");
Console.WriteLine("Remoting: {0} ms.", Test(proxy, iterations));
}
private …
Run Code Online (Sandbox Code Playgroud) 如何在node.js中创建命名管道?
PS:现在我正在创建一个命名管道,如下所示.但我认为这不是最好的方法
var mkfifoProcess = spawn('mkfifo', [fifoFilePath]);
mkfifoProcess.on('exit', function (code) {
if (code == 0) {
console.log('fifo created: ' + fifoFilePath);
} else {
console.log('fail to create fifo with code: ' + code);
}
});
Run Code Online (Sandbox Code Playgroud) named-pipes ×10
c# ×4
ipc ×2
performance ×2
pipe ×2
sockets ×2
wcf ×2
.net ×1
.net-3.5 ×1
fifo ×1
file-io ×1
linux ×1
node.js ×1
nonblocking ×1
posix ×1
sql-server ×1
windows ×1