recvfrom函數和sendto函數
#include<sys/socket.h>
ssize_t recvfrom(int sockfd,void *buff,size_t nbytes,int flags,struct sockaddr *from,socklen_t *addrlen);
ssize_t sendto(int sockfd,void buff,size_t nbytes,int flags,struct sockaddr *to,socklen_t *addrlen);
其中sockfd是描述付,buff和nbytes是要發送的緩衝區和要發送的數量,最後兩個參數是將要進行發送接受的套接字.
兩個函數的返回值是所讀寫的數據量.
UDP服務器程序例子:
#include "unp.h"
int main(int argc,char **argv){
int sockfd;
struct sockaddr cliaddr,servaddr;
sockfd = socket(AF_INET,SOCKDGRAM,0);
bzero(servaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);/
bind(sockfd,(SA*)&servaddr,sizeof(servaddr));
dg_echo(sockfd,(SA*)&cliaddr,sizeof(cliaddr));
}
void dg_echo(int scokfd,SA*pcliaddr,scoklen_t clilen){
int n;
socklen_t len;
char mesg[MAXLINE];
for(;;){
len = clien;
n=recvfrom(sockfd,mesg,MAXLINE,0,pcliaddr,&len);//接收一個套接字信息
sendto(scokfd,mesg,n,0,pcliaddr,len);//發送一個套接字信息
}
}
recvfrom提供的服務器服務是迭代的而不是併發的,所以UDP引號有排隊發生.
也就是每個UDP有一個套接字接收緩衝區,當有套接字到達的時候,先到達緩衝區,然後被recvfrom以先進先出的方法調出.
#include "unp.h"
int main(int argc,char **argv){
int sockfd;
struct sockaddr servaddr;
bzero(cliaddr,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET,argv[1],*servaddr.sin_addr);
sockfd = socket(IN_INET,SOCK_DGRAM,0);
dg_cli(stdin,sockfd,(SA*)servaddr,sozeof(servaddr));
exit(0);
}
void dg_cli(FILE* fp,int sockfd,SA* pservaddr,ssize_t servlen){
int n;
char sendline[MAXLINE],recvline[MALINE+1];
while(fgets(sendline,MAXLINE,fp)!=NULL){//不是0,
sendto(scofd,sendline,MAXLINE,0,pservaddr,servlen);
n = recvfrom(scokfd,recvline,MAXLINE,0,NULL,NULL);//接收數據之後不需要發送回去,所以設置爲NULL,
recvlien[MAXLINE]=0;
Fputs(recvline);
}
}//客戶端程序中,內核會爲器指派一個臨時端口,當然也可以使用bind顯式指定,但是很少這樣做.
任何知道客戶端IP和端口號的終端都可以向客戶發送報文.
如果使用:保留服務器地址,使用recvfrom獲取接收套接字,只接收來自服務器的保溫.
上述方法正確嗎?
不正確,如果服務器單IP,那麼可以接收,但是服務器一般都是多宿的.這樣會阻擋服務器發來的部分消息.
服務器進程未運行:
服務器未運行的時候,會返回一個ICMP錯誤,但是這個ICMP錯誤不直接返回給進程,是返回給內核的。
因爲,recvfrom收到只能errno,errno不能發出錯誤詳情。
多宿客戶捆綁IP到其套接字:
直接結果就是,IP數據報可能會包含,一個不同於外出鏈路IP的源IP地址。
connect
如果對UDP進行連接,那麼可以使用connect,使用之後,就不能使用sendto和recvfrom來進行收發,而使用read和write。
給一個已經連接的UDP多次調用connect可出於一以下目的之一
1 指定新的IP地址和端口號
2 斷開套接字