2013-05-30 31 views
0

我是socket編程的新手。 當學習sendto功能,爲原型:爲什麼sendto函數需要第三個參數,在socket編程中

ssize_t sendto(int socket, const void *message, size_t length, 
       int flags, const struct sockaddr *dest_addr, 
       socklen_t dest_len); 

我結識了「消息」已經包含目標IP,和dest_addr說法也指定了目標IP地址。 dest_addr參數有其他用法嗎?

回答

0

消息確實不是包含目標地址,只包含有效負載字節。

除非您使用原始套接字......並且如果您是套接字編程的新手,則不應該這樣做。

+0

是的,我很抱歉的問題的部分狀態。我正在使用原始套接字發送ICMP消息。很明顯,你對套接字非常熟悉。你能告訴我,「dest_addr」是否在行scket中是無效的嗎? – Akr

+0

@Akr:原始插座,呃?那麼,從'man 7 raw':「發送到原始套接字應該採用來自sin_port的IP協議;這種能力在Linux 2.2中丟失了。解決方法是使用IP_HDRINCL」。所以我的猜測是'dest_ *'參數大多被忽略了,你最好用'send'而不是'sendto'。 – rodrigo

3

不,郵件中包含你會送什麼,這裏有一個例子:

int spatula_count = 3490; 
char *secret_message = "The Cheese is in The Toaster"; 

int stream_socket, dgram_socket; 
struct sockaddr_in dest; 
int temp; 

// first with TCP stream sockets: 

// assume sockets are made and connected 
//stream_socket = socket(... 
//connect(stream_socket, ... 

// convert to network byte order 
temp = htonl(spatula_count); 
// send data normally: 
send(stream_socket, &temp, sizeof temp, 0); 

// send secret message out of band: 
send(stream_socket, secret_message, strlen(secret_message)+1, MSG_OOB); 

// now with UDP datagram sockets: 
//getaddrinfo(... 
//dest = ... // assume "dest" holds the address of the destination 
//dgram_socket = socket(... 

// send secret message normally: 
sendto(dgram_socket, secret_message, strlen(secret_message)+1, 0, 
     (struct sockaddr*)&dest, sizeof dest); 
6

我認爲你是混亂的「信息」和「dest_addr」。

讓我們來看看原型擴展形式的sendto:

ssize_t sendto (int sockfd, 
       const void *buf, 
       size_t length, 
       int flags, 
       const struct sockaddr *dest_addr, 
       socklen_t addrlen); 

的sockfd - 這是您提供呼叫建立與socket插座()

BUF - 這是一個指向數組的指針OF BYTES(即他們可以製作char *類型的buf)。也就是說,這是您希望通過封裝在UDP數據包中的線路發送的數據。

長度 - 這是該數組中有多少個字節。如果你沒有通過「長度」,它不知道「buf」是1字節還是10000字節。

標誌 - 通常是0。這是先進的東西

dest_addr - 這是一個指針到目的地址。通常,您初始化一個sockaddr_in實例並將其指針值轉換爲sockaddr *類型。

addrlen - dest_addr的大小。通常是sizeof(sockaddr_in)。地址長度是可變的,因爲dest_addr可能指向IPV4地址(sockaddr_in類型)或IPV6地址(sockaddr_in6類型)或某種其他類型。

從本地端口9999向其端口8888上的遠程主機「1.2.3.4」發送數據包的示例。爲簡潔起見,省略了返回碼的錯誤檢查。

int s; 
sockaddr_in addrDest; 
sockaddr_in addrLocal; 
char* msg = "Hello World"; 

// create the socket 
s = socket(AF_INET, SOCK_DGRAM, 0); // UDP socket 


addrLocal.sin_family = AF_INET; 
addrLocal.sin_port = htons(9999); 
addrLocal.sin_addr = INADDR_ANY; // zero-init sin_addr to tell it to use all available adapters on the local host 

// associate this socket with local UDP port 9999 
result = bind(s, (struct sockaddr*)&addrLocal, 0); 

// send "Hello world" from local port 9999 to the host at 1.2.3.4 on its port 8888 
addrDest.sin_family = AF_INET; 
addrDest.sin_port = htons(8888); 
addrDest.sin_addr.s_addr = inet_addr("1.2.3.4"); 

// strlen(msg)+1 for terminating null char 
result = sendto(s, msg, strlen(msg)+1, 0, (struct sockaddr*)&addrDest, sizeof(addrDest)); 
相關問題