2011-09-05 26 views
1

我這裏有以下問題:我想寫一個特定端口的UDP套接字服務器流式數據,以及客戶端應該能夠連接到它,並接收被髮送出去,沒有太多的數據非常麻煩:他們只是連接,從他們開始的那一刻起,他們應該從服務器使用recvfrom獲取數據。流的UDP

我有一些問題設置網絡相關的部分。所以,這裏是一個粗略的一段代碼,我儘量讓工作:

int udpSock = socket(AF_INET, SOCK_DGRAM, 0); 
if(udpSock == -1) 
{ 
    perror("Could not create audio output socket"); 
    exit(1); 
} 

struct sockaddr_in *sin = (struct sockaddr_in*)&gOutgoingAddr; 
sin->sin_port = htons(40200); 
if(bind(udpSock, (const sockaddr*)sin, sizeof(struct sockaddr_in)) == -1) 
{ 
    perror("Cannot bind audio socket"); 
    exit(1); 
} 

int buffer_size = 0; 
char* data = get_next_buffer(&buffer_size); 
while(buffer_size > 0) 
{ 
    if(sendto(udpSock, (const void*)(data), buffer_size, 0, NULL, 0) == -1) 
    { 
     perror("sendto failure"); 
    } 
    data = get_next_buffer(&buffer_size); 
} 

不要擔心gOutgoingAddr變量,它是使用​​正確獲得,它是有效的。我很困擾關於sendto方法的參數化,becasue對現在的應用程序的輸出是:

sendto failure: Destination address required 

這是真的,因爲我沒有目標地址,因爲所有的例子,我發現到現在顯示服務器何時獲得客戶端連接,並且有地址。但由於我還沒有客戶端連接,我仍然想流出。

我感謝所有幫助,我不知道是什麼Ishould把爲SENDTO的參數:

  1. 的gOutgoingAddress這是我創建套接字的地址?我試過這個,但是如果我在指定的端口上使用tcpdump linux命令,我什麼也得不到。
  2. 我應該創建一個組播套接字?這在某種程度上是沒有意義的...
  3. 別的東西嗎?

感謝, FRC

回答

2

您不能流出來「無門」。通過UDP流式傳輸數據不是多播。這意味着如果您連接了100個客戶端,則必須將完全相同的數據發送100次,一次發送給每個應接收它的客戶端。多播不是最初的IPv4設計的一部分。它後來被添加,並沒有得到廣泛的支持。這與IPv6相反,其中多播已成爲初始設計的一部分。您可以做的唯一一件事就是在您的本地網絡中廣播流量。這隻適用於所有客戶端都在您的本地網段。要廣播您的服務器,只需將數據發送到255.255.255.255和一個固定的UDP端口。所有的客戶端都必須監聽特定的端口並接收數據。請注意,在大多數系統中,您需要特殊的廣播許可權(例如,只有以root權限運行的程序才允許廣播流量,這是不常見的,因爲廣播會污染您的網絡,因爲所有廣播數據包都會發送到網絡中的所有客戶端,不管他們是否關心他們)。沒有廣播,你只有單播和單播意味着一個發送者,一個接收者。對於一個發送者多個接收者,您必須多次發送相同的數據到多個地址。

+1

多播由許多(如果不是大多數)現代路由器支持。互聯網服務提供商可能不支持它。例如,見[BBC,Virgin Radio,EMAP和GCAP已經開始通過多播傳送他們的無線電](http://www.bbc.co.uk/multicast/radio/index.shtml)。 –

+0

我的回答並不是指骨幹互聯網路由器。我指的是您在家庭和小型辦公網絡中找到的典型設備,它們沒有IPv4多播支持,除此之外它還沒有第2層(以太網)多播支持,而是使用廣播來代替多播地址。 – Mecki

0

什麼是audioUdpSock的方式? 你不是應該使用udpSock嗎?

+0

問題編輯:) audioUdpSock是udpSock,我只是修剪了原始源丟棄一切與問題 – fritzone

+0

確定:) OK我沒有明白。您正在嘗試流式傳輸,但您沒有任何地址?或者,當請求出現時,您正嘗試將流式傳輸到某個地址? –

+0

我正在嘗試流式傳輸,而我沒有地址。我希望多個客戶端能夠連接到我的服務器,並開始從他們連接的點接收數據。 – fritzone

0

在你的服務器做一個recvfrom,並讓客戶端發送消息(你想要的任何內容,這僅僅是一個建立連接,一個問候的方式)。然後服務器將擁有來自recvfrom的客戶端地址,並可以向其發送數據包。

由於UDP套接字是無連接的(有使用UDP套接字時無需acceptconnect),你需要有另一種方式來通知客戶端存在的服務器(和客戶端需要有一個通常,用戶給它,或者它是硬編碼的)以外的方式來知道服務器地址。

如果你可以有多個客戶端,那麼你就必須使用selectpoll,...在插座上,以知道什麼時候是安全調用recvfrom而不阻塞(或者你可以配置你的插座是非阻塞)。

編輯:我強烈建議Beej's Guide to Network Programming給大家,對於你的問題,你可以直接去Datagram Socket的樣本用法。

+0

謝謝,我會試一試並在此處發佈更新。 – fritzone