Threads and processes are very similar but they differ in the way they share resources. Processes are normally independent and have its own address space. Now the question comes when 2 independent processes want to communicate how do they do that. There are quite a few options for them to establish a good amount of communication protocol. Some of them are listed below. 1. Message passing. 2. Through Socket communication. 3. Named piped communication. I will be mainly focusing on Named piped Communication. We start a server in a low priority thread. Code: CPipeSampleDlg *pPipeDlg = (CPipeSampleDlg*)lpData; while(TRUE) { BOOL fConnected,fSuccess; CHAR chRequest[MAX_PATH]; DWORD cbBytesRead; // If Pipe server is stopped break from the loop. if(pPipeDlg->m_PipeHandle == NULL) break; fConnected = ConnectNamedPipe(pPipeDlg->m_PipeHandle, NULL) ? TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); if (fConnected) { fSuccess = ReadFile (pPipeDlg->m_PipeHandle, // handle to pipe chRequest, // buffer to receive data MAX_PATH, // size of buffer &cbBytesRead, // number of bytes read NULL); // not overlapped I/O chRequest[cbBytesRead] = '\0'; CString msg; msg.Format("Received string : %s\r\n",chRequest); pPipeDlg->ShowLastError(msg); FlushFileBuffers(pPipeDlg->m_PipeHandle); DisconnectNamedPipe(pPipeDlg->m_PipeHandle); } } return 0; The thread waits for a client to connect to it as passes some data to the server. Code: CString szPipeName; szPipeName = _T("\\\\.\\pipe\\PipeTest"); BOOL bret = FALSE; //first we will try to connect to the exising PIPE bret = ::WaitNamedPipe((LPCSTR)szPipeName,PROVIDER_WAIT_TIME); //the named if(bret == FALSE) { ShowLastError(); return; } else { //the PIPE is available so we will do the rest of the work in a thread ShowLastError("PIPE is available for connection"); BOOL flg; DWORD dwWrite; CString szPipeUpdate; HANDLE hPipeHandle = ::CreateFile((LPCSTR)szPipeName,GENERIC_WRITE,0,NULL, OPEN_EXISTING,0,NULL); szPipeUpdate = _T("WM_USER_MESSAGE"); flg = WriteFile(hPipeHandle, szPipeUpdate, strlen(szPipeUpdate), &dwWrite, NULL); if (FALSE == flg) ShowLastError("Sending string : " + szPipeUpdate + " Failed"); else ShowLastError("Sending string : " + szPipeUpdate); CloseHandle(hPipeHandle); } The client connects to the pipe creates a file to be wriiten. Writes the file and returns. It does not wait for the server to complete the process with the data. This is asynchronous mode of tranfer. I have used the name of the pipe as "\\\\.\\pipe\\PipeTest" which connects to the server on the local machine but it can be used to specify some other name of the server or even the ip address where the server is running like "\\\\127.0.0.1\\pipe\\PipeTest" I have similar code in VB with same API's for you to see. Server code Code: Dim ovl As OVERLAPPED Dim fConnected, fSuccess As Boolean Dim iConnectionStatus As Long Dim chRequest As String Dim cbBytesRead As Long Do DoEvents If PipeHandle = 0 Then Exit Do End If iConnectionStatus = ConnectNamedPipe(PipeHandle, ovl) If iConnectionStatus <> 0 Then fConnected = True Else If Err.LastDllError = ERROR_PIPE_CONNECTED Then fConnected = True Else fConnected = False End If End If If fConnected = True Then chRequest = Space(MAX_PATH) fSuccess = ReadFile(PipeHandle, chRequest, MAX_PATH, cbBytesRead, ovl) If Not fSuccess Or cbBytesRead = 0 Then Exit Do End If ShowLastStatus "Recieved : " + chRequest FlushFileBuffers ByVal PipeHandle DisconnectNamedPipe ByVal PipeHandle End If Loop Client code Code: Dim bret As Boolean bret = False bret = WaitNamedPipe(szPipeName, PROVIDER_WAIT_TIME) If bret = False Then ShowLastStatus Else ShowLastStatus "PIPE is available for connection" Dim flg As Boolean Dim dwWrite As Long Dim szPipeUpdate As String Dim hPipeHandle As Long Dim sa As SECURITY_ATTRIBUTES Dim ovl As OVERLAPPED hPipeHandle = CreateFile(szPipeName, GENERIC_WRITE, 0, sa, OPEN_EXISTING, 0, 0) szPipeUpdate = "HI FROM CLIENT" flg = WriteFile(hPipeHandle, szPipeUpdate, Len(szPipeUpdate), dwWrite, ovl) If False = flg Then ShowLastStatus "Sending string : " + szPipeUpdate + " Failed" Else ShowLastStatus "Sending string : " + szPipeUpdate End If End If API's Code: 'Constants Public Const PROVIDER_WAIT_TIME = 30 Public Const PIPE_ACCESS_DUPLEX = &H3 Public Const FILE_FLAG_OVERLAPPED = &H40000000 Public Const PIPE_TYPE_MESSAGE = &H4 Public Const PIPE_WAIT = &H0 Public Const MAX_PATH = 260 Public Const INVALID_HANDLE_VALUE = -1 Public Const FORMAT_MESSAGE_ALLOCATE_BUFFER = &H100 Public Const FORMAT_MESSAGE_FROM_SYSTEM = &H1000 Public Const FORMAT_MESSAGE_IGNORE_INSERTS = &H200 Public Const LANG_NEUTRAL = &H0 Public Const GENERIC_WRITE = &H40000000 Public Const OPEN_EXISTING = 3 Public Const ERROR_PIPE_CONNECTED = 535& 'Types Public Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Long End Type Public Type OVERLAPPED Internal As Long InternalHigh As Long offset As Long OffsetHigh As Long hEvent As Long End Type 'Functions Public Declare Function CreateNamedPipe Lib "kernel32" Alias "CreateNamedPipeA" (ByVal lpName As String, ByVal dwOpenMode As Long, ByVal dwPipeMode As Long, ByVal nMaxInstances As Long, ByVal nOutBufferSize As Long, ByVal nInBufferSize As Long, ByVal nDefaultTimeOut As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long Public Declare Function FormatMessage Lib "kernel32" Alias "FormatMessageA" (ByVal dwFlags As Long, lpSource As Any, ByVal dwMessageId As Long, ByVal dwLanguageId As Long, ByVal lpBuffer As String, ByVal nSize As Long, Arguments As Long) As Long Public Declare Function ConnectNamedPipe Lib "kernel32" (ByVal hNamedPipe As Long, lpOverlapped As OVERLAPPED) As Long Public Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long Public Declare Function FlushFileBuffers Lib "kernel32" (ByVal hFile As Long) As Long Public Declare Function DisconnectNamedPipe Lib "kernel32" (ByVal hNamedPipe As Long) As Long Public Declare Function WaitNamedPipe Lib "kernel32" Alias "WaitNamedPipeA" (ByVal lpNamedPipeName As String, ByVal nTimeOut As Long) As Long Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long Public Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long I am not a VB expert and if I you have any suggestion feel free to post a comment. No need to copy and paste the code as I have attached the VB and VC Source codes for you to download.
should i serialize the file before sending it? i replace "szPipeUpdate = _T("WM_USER_MESSAGE");" by what plz?
Refer to the following articles for that. [thread=2977]File read write in plain C[/thread]. [thread=1323]File Handling in C - File Pointers[/thread]. [thread=1268]File Splitter and Merger[/thread].
i think i going to read each pixel of the jpg image and send them in series in a string and i reassemble them at destination...
I have a console exe, which simple does like this. _tprintf(_T("Hello...")); Sleep(2000); _tprintf(_T("Good Morning..")); Sleep(3000); _tprintf(_T("How r u??")); I want invoke this exe from my Dialog appication, and display these outputs in a ListBox. I did it using CreatePipe(), CreateProcess() and ReadFile() functions. But the problem now is when execution reaches the ReadFile() function, it stucks for some time(upto the completion of child process) . And instead of getting "Hello", RedFile() reads entire output texts ("Hello.. GoodMorning..How r u??") as a whole. But what i want is to instantly read the output of child exe whenver it prints a new text.. Wht to do??