#include <sys/types.h>
#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *from, int *fromlen);
返回:大于0-成功接收數(shù)據(jù)長度连茧;-1-出錯;
UDP套接字使用無連接協(xié)議,因此必須使用recvfrom函數(shù),指明源地址;本函數(shù)從(已連接)套接口上接收數(shù)據(jù)罐韩,并捕獲數(shù)據(jù)發(fā)送源的地址。
flags是傳輸控制標(biāo)志,其值定義如下:
0:常規(guī)操作绞绒,如同read()函數(shù);
from 和 fromlen 是“數(shù)據(jù)源地址-長度”參數(shù)榕暇。
#include <sys/types.h>
#include <sys/socket.h>
ssize_t sendto(int sockfd, const void *msg, size_t len, int flags, const struct sockaddr *to, int tolen);
返回:大于0-成功發(fā)送數(shù)據(jù)長度蓬衡;-1-出錯;
UDP套接字使用無連接協(xié)議彤枢,因此必須使用sendto函數(shù)狰晚,指明目的地址;
flags是傳輸控制標(biāo)志缴啡,其值定義如下:
0:常規(guī)操作壁晒,如同write()函數(shù);
代碼實戰(zhàn)
/*udpclient.c*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include<stdlib.h>
#include<errno.h>
int main(int argc, char *argv[])
{
int fd;
struct sockaddr_in server,peer;
char rbuf[100];
socklen_t len;
int num;
if (argc !=3)
{
printf("Usage: %s <IP Address> <message>\n", argv[0]);
exit(1);
}
fd=socket(AF_INET, SOCK_DGRAM, 0);
if (fd==-1)
{
perror("socket");
exit(1);
}
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(1234);
server.sin_addr.s_addr = inet_addr(argv[1]);
//發(fā)送數(shù)據(jù)
num=sendto(fd,argv[2],strlen(argv[2]),0,(struct sockaddr *)&server,sizeof(server));
printf("client send %d bytes\n",num);
len=sizeof(server);
while(1)
{
//if(strncmp(argv[2],"bye",3)==0)
// break;
//接收數(shù)據(jù)
num=recvfrom(fd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&peer,&len);
if(num==-1)
{
printf("recvfrom errno is %d\n",errno);
break;
}
rbuf[num]='\0';
//比較是否是服務(wù)器地址
// memcmp是比較內(nèi)存區(qū)域buf1和buf2的前count個字節(jié)业栅。該函數(shù)是按字節(jié)比較的秒咐。
if(len != sizeof(server) || memcmp(&server,&peer,len)!=0)
{
printf("message not from server!\n");
continue;
}
//輸出信息
printf("server message:%s.\n",rbuf);
break;
}
close(fd);
}
/*udpserver.c*/
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include<stdlib.h>
int main(void)
{
int sockfd;
struct sockaddr_in server,client;
int port = 1234;
int opt = SO_REUSEADDR;
int rt;
int addrlen;
char sendbuf[100];
char rbuf[100];
int num;
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd==-1)
{
perror("socket");
exit(1);
}
//避免出現(xiàn)地址已經(jīng)使用的錯誤
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("127.0.0.1"); //回送地址,指本地機碘裕,一般用來測試使用
server.sin_port = htons(port);
rt=bind(sockfd, (struct sockaddr *)& server, sizeof(server));
if (rt== -1)
{
perror("bind");
exit(1);
}
addrlen=sizeof(client);
while(1)
{ //接收客戶端信息
num=recvfrom(sockfd,rbuf,sizeof(rbuf),0,(struct sockaddr *)&client,&addrlen);
if(num<0)
{
perror("recvfrom");
break;
}
rbuf[num]='\0';
//顯示客戶端信息携取,如果客戶端發(fā)來bye則退出循環(huán)
printf("Got a message <%s> from client.\nIt's IP is %s,port is %d.\n", rbuf,inet_ntoa(client.sin_addr),ntohs(client.sin_port));
if(strcmp(rbuf,"bye")==0)
break;
//向客戶端發(fā)送welcome
sprintf(sendbuf,"welcome!");
num=sendto(sockfd,sendbuf,strlen(sendbuf),0,(struct sockaddr *)&client,addrlen);
printf("server send %d bytes\n",num);
}
close(sockfd);
}