2014-04-27 31 views
1

我知道這顯然是基本的問題,我知道有很多教程和準備去的例子,但我必須錯過一些東西。我試圖通過UDP套接字發送文本(char *)到本地網絡中的其他機器。到目前爲止,我嘗試了一些教程,如http://gafferongames.com/networking-for-game-programmers/sending-and-receiving-packets/等,但是我總是在使用errno的函數bind()中發生錯誤「無法分配請求的地址」。發送在Linux的UDP套接字 - C語言

我只是在char數組中有一些數據,我想通過網絡將它們推送到另一個主機。有人能請我指出正確的方向嗎?我需要套接字服務器還是客戶端?我是否需要將套接字綁定到某個接口?

這是我的遊樂場:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <arpa/inet.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <fcntl.h> 
#include <errno.h> 

int handle; 

int init_socket() 
{ 
     handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 

     if (handle <= 0) 
     { 
       printf("failed to create socket\n"); 
       return 1; 
     } 

     printf("sockets successfully initialized\n"); 

     return 0; 
} 

int main() 
{ 
     unsigned short port = 30000; 
    char * data = "hovno"; 

    init_socket(); 

     struct sockaddr_in address; 

    memset((char *) &address, 0, sizeof(address)); 

     address.sin_family = AF_INET; 
     address.sin_addr.s_addr = inet_addr("192.168.11.129"); // this is address of host which I want to send the socket 
     address.sin_port = htons(port); 


    printf("handle: %d\n", handle); // prints number greater than 0 so I assume handle is initialized properly 

     if (bind(handle, (const struct sockaddr*) &address, sizeof(struct sockaddr_in)) < 0) 
     { 
       printf("failed to bind socket (%s)\n", strerror(errno)); // Cannot assign requested address 
       return 1; 
     } 

     int nonBlocking = 1; 
     if (fcntl(handle, F_SETFL, O_NONBLOCK, nonBlocking) == -1) 
     { 
       printf("failed to set non-blocking\n"); 
       return 2; 
     } 

     int sent_bytes = sendto(handle, data, strlen(data), 0, (const struct sockaddr*) &address, sizeof(struct sockaddr_in)); 

     if (sent_bytes != strlen(data)) 
     { 
       printf("failed to send packet\n"); 
       return 3; 
     } 

    return 0; 
} 
+0

你應該'綁定_local_地址(或者根本不綁定它,如果你不關心發送套接字的端口號)。遠程地址在'sendto'中指定。您不能將遠程地址綁定到本地套接字,這不是「綁定」的工作方式。 您仍然需要在服務器端調用'bind'來指定端口號。 – Inspired

+0

我嘗試發送數據,所以這是我應該使用udp套接字的服務器部分?所以我需要綁定兩個地址?第一個地址是我的服務器本地地址,在sendto部分我指定了我想要發送數據的地址?我需要指定確切的端口,因爲我嘗試將此數據發送到VoIP客戶端,以便此客戶端可以以正確的方式處理數據(客戶端在特定端口上偵聽)。 – Cockootec

+0

發送端應該調用'socket'和'sendto'。不需要調用'bind',你不必調整套接字的本地地址。遠程地址在'sendto'中指定。 只需從代碼中刪除「綁定」部分,它應該可以工作。 – Inspired

回答

4

bind被稱爲該本地地址(一個你打算recv包)。 IP地址必須是本機的本地IP地址,或(最常見)INADDR_ANY

通常,您根本不必在客戶端使用bind。系統會自動爲您選擇合適的自由港。

要指定UDP套接字的遠程地址,請使用sendto而不是send

如果您搜索Google的udp client c code,其中第一個結果是this one。你可以看到網絡部分基本上只有兩個呼叫,socketsendto