|
論壇說明 |
歡迎您來到『史萊姆論壇』 ^___^ 您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的! 請點擊這裡:『註冊成為我們的一份子!』 |
|
主題工具 | 顯示模式 |
2003-12-14, 08:26 PM | #1 (permalink) |
榮譽會員
|
UDP和socket函數
關鍵字 socket udp
原作者姓名 Fang 正文 以下討論關於Winsock2我的文件。 UDP是一個無連接的傳輸協定,因此socket函數connect似乎對UDP是沒有意義的, 然而事實不是這樣。 一個插口有幾個內容,其中包括傳輸協定,近端網址/連接埠,目的位址/連接埠。 對於UDP來說,socket函數建立一個插口;bind函數指明了近端網址/連接埠 (包括ADDR_ANY,通配所有本機網路接頭);connect可以用來指明目的地 址/連接埠; 一般來說,UDP客戶端在建立了插口後會直接用sendto函數傳送資料,需要 在sendto函數的參數里指明目的位址/連接埠。如果一個UDP客戶端在建立了插 口後首先用connect函數指明了目的位址/連接埠,然後也可以用send函數接受 資料,因為此時send函數已經知道對方位址/連接埠,用getsockname也可以得 到這個信息。 UDP客戶端在建立了插口後會直接用sendto函數傳送資料,還隱含了一個操作, 那就是在傳送資料之前,UDP會首先為該插口選項一個獨立的UDP連接埠(在1024 -5000之間),將該插口置為已綁定狀態。如果一個UDP客戶端在建立了插口後 首先用bind函數指明了近端網址/連接埠,也是可以的,這樣可以強迫UDP使用指 定的連接埠傳送資料。(事實上,UDP無所謂伺服器和客戶端,這裡的界限已經模 糊了。) UDP伺服器也可以使用connect,如上面所述,connect可以用來指明目的位址 /連接埠;這將導致伺服器只接受特定一個主機的請求。 驅動程式和應用程式之間通信(For Win2000 or later version) 作者 Fang 關鍵字 驅動 套用 通信 文章原始出處 根據網上一些資料整理。 正文 Q: 請問有什麼方法實現驅動程式主動和應用程式進行既時通訊,而不用應用程式採用定時查詢的方法? 比如驅動有一事件發生需要立即通知應用程式,或驅動程式需要像應用程式讀取一些內容. A: 有一個很容易的方式,在驅動程式和應用程式之間用一個事件。 在應用程式CreateFile的時候,驅動程式IoCreateSynchronizationEvent一個有名的事件,然後應用程式CreateEvent/OpenEvent此有名事件即可。 注意點: 1,不要在驅動啟始化的時候新增事件,此時大多不能成功新增; 2,讓驅動先新增,那麼此後應用程式開啟時,只能讀(Waitxxxx),不能寫(SetEvent/ResetEvent)。反之,如果應用程式先新增,則應用程式和驅動程式都有讀寫權限; 3,用名字比較理想,注意驅動中名字在\BaseNamedObjects\下,例如應用程式用「xxxEvent」,那麼驅動中就是「\BaseNamedObjects\xxxEvent」; 4,用HANDLE的方式也可以,但是在WIN98下是否可行,未知。 5,此後,驅動對讀請求應立即返回,否則就返回失敗。不然將失去用事件通知的意義(不再等待讀完成,而是有需要(通知事件)時才會讀); 6,應用程式發現有事件,應該在一個循環中讀取,直到讀取失敗,表明沒有資料可讀;否則會漏掉後續資料,而沒有及時讀取; Sample Code: // Describe the share memory. typedef struct _PKT_BUFFER { PMDL BufferMdl; PVOID UserBaseAddress; PVOID KernelBaseAddress; }PKT_BUFFER, *PPKT_BUFFER; typedef struct _SHARE_EVENT_CONTEXT { WCHAR EventName[128]; // Event name, the only connection btw ring0/ring3 HANDLE Win32EventHandle; // Ring3 copy of the event handle HANDLE DriverEventHandle; // Ring0 copy of the event handle PVOID DriverEventObject; // The event object }SHARE_EVENT_CONTEXT, *PSHARE_EVENT_CONTEXT; BOOLEAN CreateShareMemory(PPKT_BUFFER PktBuffer, ULONG Size) { PktBuffer->KernelBaseAddress = ExAllocatePoolWithTag(NonPagedPool, Size, 'MpaM'); if(!PktBuffer->KernelBaseAddress) return FALSE; // // Allocate and initalize an MDL that describes the buffer // PktBuffer->BufferMdl = IoAllocateMdl(PktBuffer->KernelBaseAddress, Size, FALSE, FALSE, NULL); if(!PktBuffer->BufferMdl) { ExFreePool(PktBuffer->KernelBaseAddress); PktBuffer->KernelBaseAddress =NULL; return FALSE; } MmBuildMdlForNonPagedPool(PktBuffer->BufferMdl); DEBUGP(DL_INFO, ("CreateShareMemory: KernelBaseAddress = 0x%p\n", PktBuffer->KernelBaseAddress)); return TRUE; } VOID DestroyShareMemory(PPKT_BUFFER PktBuffer) { if(PktBuffer->BufferMdl) { IoFreeMdl(PktBuffer->BufferMdl); PktBuffer->BufferMdl = NULL; } if(PktBuffer->KernelBaseAddress) { ExFreePool(PktBuffer->KernelBaseAddress); PktBuffer->KernelBaseAddress = NULL; } } //This function works in user dispatch code. BOOLEAN MapSharedMemory(PPKT_BUFFER PktBuffer) { if(!PktBuffer->BufferMdl) return FALSE; // // The preferred V5 way to map the buffer into user space // PktBuffer->UserBaseAddress = MmMapLockedPagesSpecify快取(PktBuffer->BufferMdl, // MDL UserMode, // Mode Mm快取d, // Caching NULL, // Address FALSE, // Bugcheck? NormalPagePriority); // Priority if(!PktBuffer->UserBaseAddress) return FALSE; DEBUGP(DL_INFO, ("MapSharedMemory SUCCESS, UserBaseAddress %p\n", PktBuffer->UserBaseAddress)); return TRUE; } VOID UnmapSharedMemory(PPKT_BUFFER PktBuffer) { if(PktBuffer->UserBaseAddress) { MmUnmapLockedPages(PktBuffer->UserBaseAddress, PktBuffer->BufferMdl); PktBuffer->UserBaseAddress = NULL; } } BOOLEAN CreateShareEvent(PSHARE_EVENT_CONTEXT ShareEvent) { UNICODE_STRING UnicodeName; WCHAR UnicodeBuffer[128] = L"\\BaseNamedObjects\\"; RtlInitUnicodeString(&UnicodeName, UnicodeBuffer); UnicodeName.MaximumLength = 128; RtlAppendUnicodeToString(&UnicodeName, ShareEvent->EventName); ShareEvent->DriverEventObject = IoCreateSynchronizationEvent(&UnicodeName, &ShareEvent->DriverEventHandle); if(ShareEvent->DriverEventObject == NULL) { ShareEvent->DriverEventHandle = NULL; DEBUGP(DL_INFO, ("CreateSynchronizationEvent FAILED Name=%ws\n", UnicodeBuffer)); return FALSE; } else { KeClearEvent(ShareEvent->DriverEventObject); DEBUGP(DL_INFO, ("CreateSynchronizationEvent SUCCESS Name=%ws DriverEventObject=%p, DriverEventHandle=%u\n", UnicodeBuffer, ShareEvent->DriverEventObject, ShareEvent->DriverEventHandle)); return TRUE; } } VOID DestroyShareEvents(PSHARE_EVENT_CONTEXT ShareEvent) { if(ShareEvent->DriverEventHandle) { ZwClose(ShareEvent->DriverEventHandle); ShareEvent->DriverEventObject = NULL; ShareEvent->DriverEventHandle = NULL; } } |
送花文章: 3,
|