sendto & recvfrom 详解
參考一:
sendto和recvfrom一般用于UDP協議中,但是如果在TCP中connect函數調用后也可以用.
sendto()和recvfrom()——利用數據報方式進行數據傳輸
1. 在無連接的數據報socket方式下,由于本地socket并沒有與遠端機器建立連接,所以在發送數據時應指明目的地址,sendto()函數原型為:
int sendto(int sockfd, const void *msg,int len unsigned int flags, const struct sockaddr *to, int tolen);
該函數比send()函數多了兩個參數,to表示目地機的IP地址和端口號信息,而tolen常常被賦值為sizeof (struct sockaddr)。Sendto 函數也返回實際發送的數據字節長度或在出現發送錯誤時返回-1。
2. recvfrom()函數原型為:
int recvfrom(int sockfd,void *buf,int len,unsigned int lags,struct sockaddr *from,int *fromlen);
from是一個struct sockaddr類型的變量,該變量保存源機的IP地址及端口號。fromlen常置為sizeof (struct sockaddr)。當recvfrom()返回時,fromlen包含實際存入from中的數據字節數。Recvfrom()函數返回接收到的字節數或當出現錯誤時返回-1,并置相應的errno。
應注意的一點是,當你對于數據報socket調用了connect()函數時,你也可以利用send()和recv()進行數據傳輸,但該socket仍然是數據報socket,并且利用傳輸層的UDP服務。但在發送或接收數據報時,內核會自動為之加上目地和源地址信息。
參考二:
|
1. sendto() 簡述:
向一指定目的地發送數據。
#include <winsock.h>
int PASCAL FAR sendto( SOCKET s, const char FAR* buf, int len, int flags,
const struct sockaddr FAR* to, int tolen);
s:一個標識套接口的描述字。
buf:包含待發送數據的緩沖區。
len:buf緩沖區中數據的長度。
flags:調用方式標志位。
to:(可選)指針,指向目的套接口的地址。
tolen:to所指地址的長度。 注釋:
sendto()適用于已連接的數據報或流式套接口發送數據。對于數據報類套接口,
請注意成功地完成sendto()調用并不意味著數據傳送到達。
sendto()函數主要用于SOCK_DGRAM類型套接口向to參數指定端的套接口發送數據報。對于SOCK_STREAM類型套接口,to和tolen參數被忽略;這種情況下sendto()等價于send()。
為了發送廣播數據(僅適用于SOCK_DGRAM),in參數所含地址應該把特定的IP地址INADDR_BROADCAST(winsock.h中有定義)和終端地址結合起來構造。通常建議一個廣播數據報的大小不要大到以致產生碎片,也就是說數據報的數據部分(包括頭)不超過512字節。
如果傳送系統的緩沖區空間不夠保存需傳送的數據,除非套接口處于非阻塞I/O方式,否則sendto()將阻塞。對于非阻塞SOCK_STREAM類型的套接口,實際寫的數據數目可能在1到所需大小之間,其值取決于本地和遠端主機的緩沖區大小。可用select()調用來確定何時能夠進一步發送數據。
在相關套接口的選項之上,還可通過標志位flag來影響函數的執行方式。也就是說,本函數的語義既取決于套接口的選項也取決于標志位。后者由以下一些值組成: 值
意義 MSG_DONTROUTE 指明數據不選徑。一個WINDOWS套接口供應商可以忽略此標志;參見2.4節中關于SO_DONTROUTE的討論。 MSG_OOB
發送帶外數據(僅適用于SO_STREAM;參見2.2.3節)。
返回值:
若無錯誤發生,send()返回所發送數據的總數(請注意這個數字可能小于len中所規定的大小)。否則的話,返回SOCKET_ERROR錯誤,應用程序可通過WSAGetLastError()獲取相應錯誤代碼。 2. recvfrom()
|
錯誤代碼:
WSANOTINITIALISED:在使用此API之前應首先成功地調用WSAStartup()。
WSAENETDOWN:WINDOWS套接口實現檢測到網絡子系統失效。
WSAEFAULT:fromlen參數非法;from緩沖區大小無法裝入端地址。
WSAEINTR:阻塞進程被WSACancelBlockingCall()取消。
WSAEINPROGRESS:一個阻塞的WINDOWS套接口調用正在運行中。
WSAEINVAL:套接口未用bind()進行捆綁。
WSAENOTCONN:套接口未連接(僅適用于SOCK_STREAM類型)。
WSAENOTSOCK:描述字不是一個套接口。
WSAEOPNOTSUPP:指定了MSG_OOB,但套接口不是SOCK_STREAM類型的。
WSAESHUTDOWN:套接口已被關閉。當一個套接口以0或2的how參數調用shutdown()關閉后,無法再用recv()接收數據。
WSAEWOULDBLOCK:套接口標識為非阻塞模式,但接收操作會產生阻塞。
WSAEMSGSIZE:數據報太大無法全部裝入緩沖區,故被剪切。
WSAECONNABORTED:由于超時或其他原因,虛電路失效。
WSAECONNRESET:遠端強制中止了虛電路。
總結
以上是生活随笔為你收集整理的sendto & recvfrom 详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Prometheus针对自己的服务器
- 下一篇: 安装配置 | 用同济邮箱账户下载matl