Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Passing Data between Processes

CRodrig
Beginner
1,382 Views

Intel Forum,

I am attempting to pass data between two processes written in Fortran.

Process A is the main process which establishes a socket connection with a Java-based process.

Process B is created from Process A using the CreateProcess function.

I am attempting to duplicate the socket within Process B from the socket established in Process A.

[ Process A Snippet ]
---------------------

      TYPE(T_STARTUPINFO) :: sinfo
      TYPE(T_PROCESS_INFORMATION) :: pinfo
      TYPE(T_WSAPROTOCOL_INFOA) :: protInfo
c
      . . .       . . .      . . .
c
c   ------------------
c   - Create Process B.
c   ------------------
c
c
      cmdLine = "C:\\Base_Dir\\Process_B.exe"
c
      cmdLine = cmdLine(1:len_trim(cmdLine)) // char(0)
c
      returnVal = CreateProcess(NULL,
     &                          cmdLine,
     &                          NULL_SECURITY_ATTRIBUTES,
     &                          NULL_SECURITY_ATTRIBUTES,
     &                          TRUE,
     &                          CREATE_PRESERVE_CODE_AUTHZ_LEVEL,
     &                          NULL,
     &                          NULL,
     &                          sinfo,
     &                          pinfo)
c
      . . .       . . .      . . .
c
c   - Create a new socket descriptor for a shared socket.
c
      status = WSADuplicateSocket(sockid,
     &                                                pinfo.dwProcessId,
     &                                                protInfo)

[ Process B Snippet ]
---------------------

      TYPE(T_WSADATA) wsaInfo
c
      . . .       . . .      . . .
c
      consock = WSASocket(AF_INET,
     &                                    SOCK_STREAM,
     &                                    IPPROTO_TCP,
     &                                    protInfo,
     &                                    0,
     &                                    0)
c
      ierror = WSAGetLastError()

Question:
--------

The MSDN website states the following in reference to SHARED SOCKETS ...

"Shared Sockets"

The WSADuplicateSocket function is introduced to enable socket sharing across processes.
A source process calls WSADuplicateSocket to obtain a special WSAPROTOCOL_INFO structure for a
target process identifier. It uses some interprocess communications (IPC) mechanism to pass the
contents of this structure to a target process. The target process then uses the WSAPROTOCOL_INFO
structure in a call to WSPSocket. The socket descriptor returned by this function will be an
additional socket descriptor to an underlying socket which thus becomes shared.

A typical example of sharing sockets is to use one process for creating sockets and establishing connections.
This process then hands off sockets to other processes that are responsible for information exchange.

As I understand, I need to pass the contents of the "protInfo" structure (previously cast as T_WSAPROTOCOL_INFO)
to Process B via some "interprocess communications (IPC) mechanism".

What would that (IPC) mechanism be? (Most efficient)

Note:

I have even thought of putting the "TYPE(T_WSAPROTOCOL_INFOA) :: protInfo" declaration with a DLL library to be shared
between the two processes, but I understand at least one member of the structure needs to be initialized to be seen across
both processes, which I cannot seem to figure out.

Has someone come across the same dilemma, and is there a working example which I may reference?

Thank you in advance.

0 Kudos
6 Replies
jimdempseyatthecove
Honored Contributor III
1,382 Views

When the processes live on the same SMP system, consider using an inter-process shared memory method such as memory mapped file. This would be for data passing. And if needed, you can create inter-process events to indicate first fill, last empty. Sockets do work at the expense of additional overhead: read from process A memory buffer, write to/through socked on A, read from socket on B, write to memory buffer on B. Whereas shared memory could be as little as increment step counter. Or as most as increment step counter, conditionally set event flag, and on other system conditionally wait for event, resume processing (note no data transfer as data is already mapped).

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
1,382 Views

I suggest looking at the DLL_Shared_Data sample we provide in DLL.zip under Samples. You are correct that a variable that is to be read-write shared across processes in a DLL has to be initialized - just using Fortran initialization for the variable. It would obviously be a bit complicated for a derived type such as T_WSAPROTOCOL_INFOA but it could be done.

      TYPE(T_WSAPROTOCOL_INFOA) :: protInfo = T_WSAPROTOCOL_INFOA(
     & 0,0,0,0,0,T_GUID(0,0,0,''),0,
     & T_WSAPROTOCOLCHAIN(0,[0,0,0,0,0,0,0]),
     & 0,0,0,0,0,0,0,0,0,0,0,'')

 

0 Kudos
CRodrig
Beginner
1,382 Views

Steve,

I implemented your code snippet into my DLL in reference to passing the WSAPROTOCOL_INFO structure to
a child process and now I am seeing the WSAPROTOCOL_INFO structure within the child process with
the correct structure member values.

TYPE(T_WSAPROTOCOL_INFOA) :: protInfo = T_WSAPROTOCOL_INFOA( ~ )

The MSDN site states:

The WSADuplicateSocket function is introduced to enable socket sharing across processes. A source process
calls WSADuplicateSocket to obtain a special WSAPROTOCOL_INFO structure for a target process identifier.

The target process then uses the WSAPROTOCOL_INFO structure in a call to WSPSocket. The socket descriptor
returned by this function will be an additional socket descriptor to an underlying socket which thus becomes shared.

The Winsock Service Provider Interface (Winsock SPI) is a specialized discipline of Winsock used to create providers.

Traditional network programming, such as enabling applications to communicate over the network, does not require use
of Winsock SPI interfaces; use standard Winsock interfaces instead.

Question:

Within the child process (Process B), would it be correct/valid to use the WSASocket function instead of the WSPSocket function?

      consock = WSASocket(AF_INET,
     &                                    SOCK_STREAM,
     &                                    IPPROTO_TCP,
     &                                    protInfo,
     &                                    0,
     &                                    0)

Am I still obligated to call the "Connect" function and connect to the socket or is the <consock> socket already shared
and in a 'connected' state such that I may start sending/receiving on the socket descriptor?

Any issues connecting to an already existing/connected socket?

Thanks again.

0 Kudos
Steven_L_Intel1
Employee
1,382 Views

Someone else will have to comment on sockets. There are several discussions about sockets in this forum - use the search box inside the "Announcements" box on the forum main page to search only in this forum for "socket".

0 Kudos
CRodrig
Beginner
1,382 Views

Steve,

I will search the Forum for "socket" as you recommended.

Appreciate all your help!

 

0 Kudos
CRodrig
Beginner
1,382 Views

Steve,

Could you please provide an example on how to initialize the IN_ADDR structure as well
as the the SOCKADDR_IN structure within a DLL?

For Windows:

typedef struct sockaddr_in {
  ADDRESS_FAMILY sin_family;
  USHORT         sin_port;
  IN_ADDR        sin_addr;
  CHAR           sin_zero[8];
} SOCKADDR_IN

typedef struct in_addr {
  union {
    struct {
      u_char s_b1,s_b2,s_b3,s_b4;
    } S_un_b;
    struct {
      u_short s_w1,s_w2;
    } S_un_w;
    u_long S_addr;
  } S_un;
} IN_ADDR

I would like to place the declaration within a DLL to share across processes as was done with TYPE(T_WSAPROTOCOL_INFOA) :: protInfo

I have tried numerous attempts, but have been unable to compile.

Thank you in advance.

0 Kudos
Reply