2011-03-18 62 views
2

我想制作客户端服务器程序,其中服务器是主进程,客户端是子进程。在客户端,我想将stdout和stderr流子进程重定向到套接字。在服务器中,我想从套接字文件描述符中读取数据并从中读取数据。在互联网上有很多关于套接字的信息,但我没有发现任何通过用于Windows的套接字的父子IPC的例子。如何在winapi中将子进程的stdout(stderr)重定向到套接字?

如果可能的话请在这里发布一个简单的代码来解决我的问题(或部分)。 MSDN的链接也可以提供帮助,但我想我已经在那里查看了所有内容,但没有找到我想要的内容。

P.S.请不要建议管道。我想通过套接字来做到这一点。

+0

这将是非常具体的实现。我将假设windows是唯一的平台和操作系统要求。您愿意使用哪种编译器,IDE和库? – AJG85 2011-03-18 16:22:47

+0

我正在使用visual studio。我想使用standart库和winapi,作为我更喜欢socket2的套接字。但也可以使用cygwin库。 – 2011-03-18 16:25:41

+0

哪部分你有问题 - 绑定+监听套接字,连接套接字或重定向IO? – Rup 2011-03-18 16:27:02

回答

1

看看Netcat如果你可以使用它或在sourceforge的某处找到windows版本的源代码,可能会使用管道拦截stdin/stdout,并使用这些管道发送和读取套接字。

我知道你说没有管道,但没有其他的方式来做到这一点只有Windows API。你需要至少大概如下:

CreatePipe

WriteFile

ReadFile

+0

谢谢。但我已经通过管道做到了这一点))但是没有问题。管道不支持select()那就是为什么我需要套接字。 – 2011-03-18 16:45:38

+0

您可以使用重叠的I/O模型和'WaitForMultipleObjects'从多个管道读取或管理。它不像套接字列表中的Select()那么好,但是它是一种放弃的方式。你有多少客户运行,你需要重定向到服务器? – AJG85 2011-03-18 17:00:35

+0

是@ AJG85我也可以这样做。但这是另一个问题。如果我这样做,那么我需要以非阻塞模式读取表单管道。在Windows中,我无法生成文件HANDLES非阻塞我只能通过低级别的ReadFile函数以nonblocing模式读取。但是我想从这个句柄中创建FILE *然后通过fgets读取。 – 2011-03-18 17:13:25

0

这就好比试图救火其启动后,当你要试图阻止首先是火灾。

由于您是server.exe和client.exe的宣称作者,而不是尝试捕获stdout/stderr,并在此时将其重定向到套接字,因此您应该重新设计客户端,重新捕捉发往stdout的文本,然后转到stdout。

在这一点上,你可以发送输出文本到BOTH标准输出和一个套接字,如果你愿意。

编辑:忽略上半部分,因为你后来说你不是客户的作者。

好了,第二次尝试:

因为你是产卵的“真实”的客户端,使用“假”的客户,你为什么不只是拦截上的“假货”标准输入“真实”的客户端的标准输出客户端(打开管道)。然后有 “假” 的客户端将数据发送回插座..

+0

我不是真正的客户端的作者。我只是虚假客户端的作者,它应该只连接到服务器,然后自己产生真正的客户端,stdout和stdoerr必须重定向。 – 2011-03-18 16:54:01

+0

@J T查看@ AJG85s的评论回答 – 2011-03-18 17:03:33

+0

这个想法并不是在客户端和服务器之间打开管道,只是在“假”客户端和“真实”客户端之间打开管道。 “假”客户端仍然会通过套接字发送其数据,因此您的服务器仍然可以复用所有传入请求并仅在一个进程上运行。 – 2011-03-18 17:07:43

0

假设:

server talks with client 

client spawns child 

下面是从MSDN一个例子不幸的是创建一个Child Process with Redirected IO

,你必须使用管道将子程序中的IO传给客户端。没有ifs,ands或buts关于它。

然后你可以使用类似下面来获取信息到服务器:

客户端通讯科环:

while (/* files are open */) { 
    DWORD dwRead; 
    CHAR chBuf[1024]; memset(chBuf, 0, 1024); /* always initialize your memory! */ 
    BOOL bSuccess = FALSE; 

    /* read data from child pipe */ 
    ReadFromFile(g_hSChildStd_IN_Rd, chBuf, 1024, &dwRead, NULL);  

    /* send data via windows sockets to the remote server connection 
     represented by serverSocketHandle */ 
    send(serverSocketHandle, chBuf, dwRead, 0); 
} 

你的客户,实际上成为STDOUT/ERR管之间的翻译和一个TCP套接字。

+0

@Chris你想说什么? – 2011-03-18 17:04:12

+0

我在问题中写道不建议管道。 – 2011-03-18 17:08:10

+0

Mihran,如果你不能修改可执行的“真实”客户端,你必须以某种方式拦截STDOUT/ERR。你真的应该重新考虑使用管道。 – 2011-03-18 17:11:51

0

我知道支持这个的唯一环境是Cygwin。他们是开源的 - 尝试仔细阅读他们的代码以获取想法。不过,这确实是非常令人讨厌的,其中包括像四处抽线的东西。

相关问题