네트워크라는 개념이 생성되면서, 여러가지 계층간 통신이 생겨났다.
일반적으로 어플리케이션 개발자들이 사용하는 통신은 최상위 계층을 다루게 되며..
주로 소켓통신, 혹은 파이프와 같은 것을 이용하여 로컬 프로세스간 혹은 원격지 프로세스간에
통신을 하게된다.

여기서는 메시지를 주고받은 통신에서, 데이터를 공유하는 것을 통털어... 알고 있는것만 정리한다. -0-;;;
모르는 것을 어떻게 하나 ^^;;; (누가좀..)

이 계통에 들어선지 시간이 좀 흘럿지만, 참으로 다양한 방식이 존재하고..
공부해야할 것도 너무 많다.. -0-;;;

1. SOCKET - 통신
   통신 프로그램을 짜면 가장 먼저 접하는 것이 소켓이다. 하위호환 덕택에 아직도 명맥을 유지하는 BSD 모델과
   winsock으로 불리우는 2가지 모델을 윈도우에서 제공해준다.
   서버/클라이언트 모델로 제공되며, TCP/UDP 이렇게 상위 2가지를 주로 사용한다.
   (이건 머, 어떻게 심플하게 설명할 방법이 없다... 책사서 봐야지 ㅋ~)

2. ATOM - 공유
   시스템에서 제공하는 테이블을 이용하여, 문자열 데이터를 공유할 수 있도록 제공해준다.
   ATOM 이라고 불리우는 2바이트 숫자를 키 값으로 이용하여 255바이트까지의 문자열을 해당 시스템의 테이블에
   저장하고, 가져다 쓸 수 있다.  사용방법이 너무 간단하고, 윈도우 95까지도 지원한다.
   함수도 아래의 6개가 다이고, 그나마 로컬과 글로벌을 구분하기 위한 정도뿐이다. 

   9번 DDE 섹션을 보면, ATOM과 SendMessage 를 이용하여, 어떻게 데이터 통신을 할 수 있는지
   다양함 샘플을 보여준다. 

 
3. PIPE - 통신
   로컬머신, 혹은 로컬 네트웍 그룹내에서 사용이 가능한 통신 방식이다. 소켓보다 조금 들 복잡하지만 소켓처럼
   정밀하게 제어하기는 조금 쉽지 않다.
   이름 있는 파이프(양방향통신)과, 이름 없는 파이프(단방향통신)을 지원한다.

4. Mailslot - 통신
   메시지 큐잉을 지원하고, 비연결성이기 때문에 브로드 캐스팅을 지원한다. 사용하기가 간단하다.
   UDP와 같이 전송 보장을 지원하지 않고, 데이터크기가 400 바이트 이내라는 제한이 있다.



5. SendMessage, PostMessage - 통신
   윈도우가 존재한다는 범위내에서만 사용가능한 통신이며, WPARAM, LPARAM 에 해당하는 두개의 정수형 타입 데이터의
   전송이 가능하다. 큐잉을 보장해주지만, 윈도가 있어야한다는 제약이 있다.

6. WM_COPYDATA - 통신
   5번과 마찬가지로 윈도우의 메시지를 이용한 통신 방식이다. 매우 사용하기 쉽다. 윈도우즈 메시지 기반이기 때문에,
   메시지 펌프 처리를 해줘야한다. 메시지 통신의 빈도가 낮고, 빨리 구현하는 것이 우선이라면 이 방법이 좋을 수 있다.
   다만 메시지를 받는 쪽이 윈도우 핸들이 가지고 있어야 한다.



7. Memory Mapped File - 공유
   Memory Mapped File도 프로세스 간 통신에 이용할 수 있다. 다른 IPC들이 Memory Mapped File를 이용해서 구현되므로,
   속도가 중요하다면, Memory Mapped File이 가장 나은 선택이다.
   대량의 데이터를 다룰 때 주로 사용되지만, 매핑된 메모리를 블럭단위로 사용하게 되므로, 상호 액세스에 대한 규정을
   잘 만들어 관리해야 한다.

8. DLL Shared Sections - 공유
   DLL을 만들고 공유 영역을 설정하여 데이터를 공유하는 방식이다. 일단 DLL을 작성해야 하기 때문에 간단한 통신을 위하여
   이러한 것을 만드는 것은 조금 비효율 적이라고도 할 수 있다.
   또한 윈도우에 같은 dll 이 있다면, 경로가 서로 달라 각각의 dll을 로드하게 되면 이러한 것도 무용지물이다.

9. DDE, NetDDE - 통신
   자료를 좀 찾아보니, DDE는 SendMessage 와 ATOM을 조합하여, 시스템 ATOM 테이블을 이용한 데이터 통신이란다.
   데이터가 있을 경우는 공유메모리를 생성하여, 해당 메모리 주소를 전달하는 방식이고, 이러한 조합을 몇가지 내부적인
   메시지로 감싸서 사용자가 쉽게 사용할 수 있도록 해결해준다.



Note   If your application uses NULL atoms, you need not use the GlobalAddAtom and GlobalDeleteAtom functions. In this example, the client application creates two global atoms containing the name of the server and the name of the topic, respectively.

The client application sends a WM_DDE_INITIATE message with these two atoms in the lParam parameter of the message. In the call to the SendMessage function, the special window handle –1 directs the system to send this message to all other active applications. SendMessage does not return to the client application until all applications that receive the message have, in turn, returned control to the system. This means that all WM_DDE_ACK messages sent in reply by the server applications are guaranteed to have been processed by the client by the time the SendMessage call has returned.

After SendMessage returns, the client application deletes the global atoms.

Server applications respond according to the logic illustrated in the following diagram.

Server application response logic

To acknowledge one or more topics, the server must create atoms for each conversation (requiring duplicate application-name atoms if there are multiple topics) and send a WM_DDE_ACK message for each conversation, as illustrated in the following example.

When a server responds with a WM_DDE_ACK message, the client application should save a handle to the server window. The client receiving the handle as the wParam parameter of the WM_DDE_ACK message then sends all subsequent DDE messages to the server window this handle identifies.

If your client application uses a NULL atom for the application name or topic name, expect the application to receive acknowledgments from more than one server application. Multiple acknowledgements can also come from multiple instances of a DDE server, even if your client application does not NULL use atoms. A server should always use a unique window for each conversation. The window procedure in the client application can use a handle to the server window (provided as the lParam parameter of WM_DDE_INITIATE) to track multiple conversations. This allows a single client window to process several conversations without needing to terminate and reconnect with a new client window for each conversation.

Transferring a Single Item

Once a DDE conversation has been established, the client can either retrieve the value of a data item from the server by issuing the WM_DDE_REQUEST message, or submit a data-item value to the server by issuing WM_DDE_POKE.

Retrieving an Item from the Server

To retrieve an item from the server, the client sends the server a WM_DDE_REQUEST message specifying the item and format to retrieve, as shown in the following example.

In this example, the client specifies the clipboard format CF_TEXT as the preferred format for the requested data item.

The receiver (server) of the WM_DDE_REQUEST message typically must delete the item atom, but if the PostMessage call fails, the client must delete the atom.

If the server has access to the requested item and can render it in the requested format, the server copies the item value as a shared memory object and sends the client a WM_DDE_DATA message, as illustrated in the following example.

In this example, the server application allocates a memory object to contain the data item. The data object is initialized as a DDEDATA structure.

The server application then sets the cfFormat member of the structure to CF_TEXT to inform the client application that the data is in text format. The client responds by copying the value of the requested data into the Value member of the DDEDATA structure. After the server has filled the data object, the server unlocks the data and creates a global atom containing the name of the data item.

Finally, the server issues the WM_DDE_DATA message by calling PostMessage. The handle to the data object and the atom containing the item name are packed into the lParam parameter of the message by the PackDDElParam function.

If PostMessage fails, the server must use the FreeDDElParam function to free the packed lParam parameter. The server must also free the packed lParam parameter for the WM_DDE_REQUEST message it received.

If the server cannot satisfy the request, it sends a negative WM_DDE_ACK message to the client, as shown in the following example.

// Negative acknowledgment. 
 
PostMessage(hwndClientDDE, 
    WM_DDE_ACK, 
    (WPARAM) hwndServerDDE, 
    PackDDElParam(WM_DDE_ACK, 0, atomItem));

Upon receiving a WM_DDE_DATA message, the client processes the data-item value as appropriate. Then, if the fAckReq member pointed to in the WM_DDE_DATA message is 1, the client must send the server a positive WM_DDE_ACK message, as shown in the following example.

In this example, the client examines the format of the data. If the format is not CF_TEXT (or if the client cannot lock the memory for the data), the client sends a negative WM_DDE_ACK message to indicate that it cannot process the data. If the client cannot lock a data handle because the handle contains the fAckReq member, the client should not send a negative WM_DDE_ACK message. Instead, the client should terminate the conversation.

If a client sends a negative acknowledgment in response to a WM_DDE_DATA message, the server is responsible for freeing the memory (but not the lParam parameter) referenced by the WM_DDE_DATA message associated with the negative acknowledgment.

If it can process the data, the client examines the fAckReq member of the DDEDATA structure to determine whether the server requested that it be informed that the client received and processed the data successfully. If the server did request this information, the client sends the server a positive WM_DDE_ACK message.

Because unlocking data invalidates the pointer to the data, the client saves the value of the fRelease member before unlocking the data object. After saving the value, the client then examines it to determine whether the server application requested the client to free the memory containing the data; the client acts accordingly.

Upon receiving a negative WM_DDE_ACK message, the client can ask for the same item value again, specifying a different clipboard format. Typically, a client will first ask for the most complex format it can support, then step down if necessary through progressively simpler formats until it finds one the server can provide.

If the server supports the Formats item of the system topic, the client can determine once what clipboard formats the server supports, instead of determining them each time the client requests an item.

Submitting an Item to the Server

The client may send an item value to the server by using the WM_DDE_POKE message. The client renders the item to be sent and sends the WM_DDE_POKE message, as illustrated in the following example.


Note  Sending data by using a WM_DDE_POKE message is essentially the same as sending it by using WM_DDE_DATA, except that WM_DDE_POKE is sent from the client to the server.

If the server is able to accept the data-item value in the format rendered by the client, the server processes the item value as appropriate and sends the client a positive WM_DDE_ACK message. If it is unable to process the item value, because of its format or for other reasons, the server sends the client a negative WM_DDE_ACK message.

In this example, the server calls GlobalGetAtomName to retrieve the name of the item the client sent. The server then determines whether it supports the item and whether the item is rendered in the correct format (that is, CF_TEXT). If the item is not supported and not rendered in the correct format, or if the server cannot lock the memory for the data, the server sends a negative acknowledgment back to the client application. Note that in this case, sending a negative acknowledgment is correct because WM_DDE_POKE messages are always assumed to have the fAckReq member set. The server should ignore the member.

If a server sends a negative acknowledgment in response to a WM_DDE_POKE message, the client is responsible for freeing the memory (but not the lParam parameter) referenced by the WM_DDE_POKE message associated with the negative acknowledgment.

Establishing a Permanent Data Link

A client application can use DDE to establish a link to an item in a server application. After such a link is established, the server sends periodic updates of the linked item to the client, typically, whenever the value of the item changes. Thus, a permanent data stream is established between the two applications; this data stream remains in place until it is explicitly disconnected.

Initiating a Data Link

The client initiates a data link by posting a WM_DDE_ADVISE message, as shown in the following example.

In this example, the client application sets the fDeferUpd flag of the WM_DDE_ADVISE message to FALSE. This directs the server application to send the data to the client whenever the data changes.

If the server is unable to service the WM_DDE_ADVISE request, it sends the client a negative WM_DDE_ACK message. But if the server has access to the item and can render it in the requested format, the server notes the new link (recalling the flags specified in the hOptions parameter) and sends the client a positive WM_DDE_ACK message. From then on, until the client issues a matching WM_DDE_UNADVISE message, the server sends the new data to the client every time the value of the item changes in the server.

The WM_DDE_ADVISE message establishes the format of the data to be exchanged during the link. If the client attempts to establish another link with the same item but is using a different data format, the server can choose to reject the second data format or attempt to support it. If a warm link has been established for any data item, the server can support only one data format at a time. This is because the WM_DDE_DATA message for a warm link has a NULL data handle, which otherwise contains the format information. Thus, a server must reject all warm links for an item already linked, and must reject all links for an item that has warm links. Another interpretation may be that the server changes the format and the hot or warm state of a link when a second link is requested for the same data item.

In general, client applications should not attempt to establish more than one link at a time for a data item.

Initiating a Data Link with the Paste Link Command

Applications that support hot or warm data links typically support a registered clipboard format named Link. When associated with the application's Copy and Paste Link commands, this clipboard format enables the user to establish DDE conversations between applications simply by copying a data item in the server application and pasting it into the client application.

A server application supports the Link clipboard format by placing in the clipboard a string containing the application, topic, and item names when the user chooses the Copy command from the Edit menu. Following is the standard Link format:

application\0topic\0item\0\0

A single null character separates the names, and two null characters terminate the entire string.

Both the client and server applications must register the Link clipboard format, as shown:

cfLink = RegisterClipboardFormat("Link");

A client application supports the Link clipboard format by means of a Paste Link command on its Edit menu. When the user chooses this command, the client application parses the application, topic, and item names from the Link-format clipboard data. Using these names, the client application initiates a conversation for the application and topic, if such a conversation does not already exist. The client application then sends a WM_DDE_ADVISE message to the server application, specifying the item name contained in the Link-format clipboard data.

Following is an example of a client application's response when the user chooses the Paste Link command.

In this example, the client application opens the clipboard and determines whether it contains data in the Link format (that is, cfLink) it had previously registered. If not, or if it cannot lock the data in the clipboard, the client returns.

After the client application retrieves a pointer to the clipboard data, it parses the data to extract the application, topic, and item names.

The client application determines whether a conversation on the topic already exists between it and the server application. If a conversation does exist, the client checks whether a link already exists for the data item. If such a link exists, the client displays a message box to the user; otherwise, it calls its own SendAdvise function to send a WM_DDE_ADVISE message to the server for the item.

If a conversation on the topic does not already exist between the client and the server, the client first calls its own SendInitiate function to broadcast the WM_DDE_INITIATE message to request a conversation and, second, calls its own FindServerGivenAppTopic function to establish the conversation with the window that responds on behalf of the server application. After the conversation has begun, the client application calls SendAdvise to request the link.

Notifying the Client that Data Has Changed

When the client establishes a link by using the WM_DDE_ADVISE message, with the fDeferUpd member not set (that is, equal to zero) in the DDEDATA structure, the client has requested the server send the data item each time the item's value changes. In such cases, the server renders the new value of the data item in the previously specified format and sends the client a WM_DDE_DATA message, as shown in the following example.

In this example, the client processes the item value as appropriate. If the fAckReq flag for the item is set, the client sends the server a positive WM_DDE_ACK message.

When the client establishes the link, with the fDeferUpd member set (that is, equal to 1), the client has requested that only a notification, not the data itself, be sent each time the data changes. In such cases, when the item value changes, the server does not render the value but simply sends the client a WM_DDE_DATA message with a null data handle, as illustrated in the following example.

As necessary, the client can request the latest value of the data item by issuing a normal WM_DDE_REQUEST message, or it can simply ignore the notice from the server that the data has changed. In either case, if fAckReq is equal to 1, the client is expected to send a positive WM_DDE_ACK message to the server.

Terminating a Data Link

If the client requests that a specific data link be terminated, the client sends the server a WM_DDE_UNADVISE message, as shown in the following example.

The server checks whether the client currently has a link to the specific item in this conversation. If a link exists, the server sends the client a positive WM_DDE_ACK message; the server is then no longer required to send updates about the item. If no link exists, the server sends the client a negative WM_DDE_ACK message.

The WM_DDE_UNADVISE message specifies a data format. A format of zero informs the server to stop all links for the specified item, even if several hot links are established and each uses a different format.

To terminate all links for a conversation, the client application sends the server a WM_DDE_UNADVISE message with a null item atom. The server determines whether the conversation has at least one link currently established. If a link exists, the server sends the client a positive WM_DDE_ACK message; the server then no longer has to send any updates in the conversation. If no link exists, the server sends the client a negative WM_DDE_ACK message.

Carrying Out Commands in a Server Application

Applications can use the WM_DDE_EXECUTE message to cause a certain command or series of commands to be carried out in another application. To do this, the client sends the server a WM_DDE_EXECUTE message containing a handle to a command string, as shown in the following example.

In this example, the server attempts to carry out the specified command string. If it succeeds, the server sends the client a positive WM_DDE_ACK message; otherwise, it sends a negative WM_DDE_ACK message. This WM_DDE_ACK message reuses the hCommand handle passed in the original WM_DDE_EXECUTE message.

If the client's command execution string requests that the server terminate, the server should respond by sending a positive WM_DDE_ACK message and then post a WM_DDE_TERMINATE message before terminating. All other commands sent with a WM_DDE_EXECUTE message should be executed synchronously; that is, the server should send a WM_DDE_ACK message only after successfully completing the command.

Terminating a Conversation

Either the client or the server can issue a WM_DDE_TERMINATE message to terminate a conversation at any time. Similarly, both the client and server applications should be prepared to receive this message at any time. An application must terminate all of its conversations before shutting down.

In the following example, the application terminating the conversation posts a WM_DDE_TERMINATE message.

PostMessage(hwndServerDDE, WM_DDE_TERMINATE, 
    (WPARAM) hwndClientDDE, 0);

This informs the other application that the sending application will send no further messages and the recipient can close its window. The recipient is expected in all cases to respond promptly by sending a WM_DDE_TERMINATE message. The recipient must not send a negative, busy, or positive WM_DDE_ACK message.

After an application has sent the WM_DDE_TERMINATE message to the partner in a DDE conversation, it must not respond to messages from that partner, since the partner might have destroyed the window to which the response would be sent.

If an application receives a DDE message other than WM_DDE_TERMINATE after it has posted WM_DDE_TERMINATE, it should free all objects associated with the received messages except the data handles for WM_DDE_DATA or WM_DDE_POKE messages that do not have the fRelease member set.

When an application is about to terminate, it should end all active DDE conversations before completing processing of the WM_DESTROY message. However, if an application does not end its active DDE conversations, the system will terminate any DDE conversations associated with a window when the window is destroyed. The following example shows how a server application terminates all DDE conversations.





_M#]

+ Recent posts