所謂屏幕廣播,即是將指定計算機的的屏幕情況發送至多台電腦,使那些電腦也能夠顯示出指定計算機的電腦桌面,一般是在電子教室之類的教學軟件中使用,最近為了在我們的一個軟件中實現這個功能也費了不少功夫,所以在這里總結一下實現方法。
屏幕廣播實現起來的方法其實也就是讓指定計算機不斷的屏幕截圖,然后將這些圖片發送至其他電腦,再讓那些電腦收到圖片后顯示出來,這樣屏幕廣播的功能就實現了。今天我要說的只是如何發送這些圖片,至於屏幕截圖則有很多種方式在這里不作闡述。
之所以屏幕廣播難以實現,主要就是屏幕廣播是要把一張圖片發送至多個電腦,如果采用TCP協議進行傳輸的話則必須向每一個電腦發送一張圖片,這樣假如一張圖片是100KB,同時發送給10個計算機則需要將近1MB的數據傳輸量,這樣大的數據量顯然不能夠在實際中應用,所以在屏幕廣播時一般采用UDP協議來傳輸圖片。
UDP是一種面向無連接的協議,之所以采用UDP是因為在UDP中有一種多播的技術,UDP多播通過向一個多播組中發送一個數據,那么只要是在這個多播組中的主機都可以收到同樣的一份副本。這樣如果要向10個主機發送一個100KB的圖片的話,只要向一個多播組發送100KB的圖片,那么其他主機都可以收到,這樣即可以大大減小數據傳輸量。
編程實現起來也並不復雜,這里給出用C語言實現的思路和方法。實現多播只需要三步:1、創建UDP套接字;2、加入多播組;3開始發送(接收)
以下是具體實現:
1、首先把頭文件和庫包含進來
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
2、初始化Winsock庫並創建UDP套接字
WSADATA WSAData; WORD wVersionRequested; wVersionRequested = MAKEWORD(2,2); if (WSAStartup(wVersionRequested,&WSAData)!=0) { printf("WinSock初始化失敗\n"); return -1; } SOCKET sSender; sSender = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED); if(sSender == INVALID_SOCKET) { WSACleanup(); return -1; }
3、加入多播組
//填充廣播地址 sockaddr_in addrBroad; addrBroad.sin_family = AF_INET; addrBroad.sin_port = htons(8742); addrBroad.sin_addr.S_un.S_addr = inet_addr("224.8.8.1"); //加入廣播組 SOCKET sRecver; sRecver = WSAJoinLeaf(sSender, (SOCKADDR*)&addrBroad, sizeof(addrBroad), NULL, NULL, NULL, NULL, JL_BOTH); if (sRecver == INVALID_SOCKET) { WSACleanup(); return -1; }
4、開始發送(接收)
發送時使用sendto函數
sendto(sSender, buf, sizeof(buf), 0, (struct sockaddr*)&addrBroad, sizeof(addrBroad);
接收時使用recvfrom函數
int len = sizeof(struct sockaddr); recvfrom(sRecver, buf, sizeof(buf), 0, (struct sockaddr*)&BroadAddr, &len);
這樣多播基本上就已經實現了,不過還有幾點要注意。首先是多播地址的概念,IP地址有一部分是划分為多播地址的,大家可以自己去網上搜索;其次是每一個主機只能加入一個多播組一次,再次加入的時候就會失敗,所以在實驗的時候要拿至少兩台電腦,一台當接收方,一台當發送方;還有一點就是由於UDP並不保證數據能完整正確的到達接收方,所以這時候的屏幕廣播就會有一個問題是接收的圖片並不完整,解決方法會在下一篇中說明。