對比與TCP來說,我們知道UDP是面向無連接的而且不可靠的通信,它適合傳輸數據量不大的數據且對數據的可靠性要求不高,由於它是無連接的所以它的數據傳輸效率比較高,也適合也對實時性要求較高的場合如:音視頻的聊天等.
本文將介紹在Linux下如何對UDP進行編程,全文通過代碼加註釋的形式進行講解.
Linux下的UDP編程可以類比於發短信:
編程流程:
服務器:
1. 創建數據報套接字(socket(SOCK_DGRAM))——————-有手機
2. 指定本地的網絡信息(struct sockaddr_in)——————-有號碼
3. 綁定網絡信息(bind())————————————–綁定號碼
4.接收/發送信息 recvfrom()/sendto()—————————收/發短息
5.關閉套接字close()——————————————-收發完畢
客戶端:
1.創建數據報套接字(socket(SOCK_DGRAM))———————手機
2.指定服務器的網絡信息(sockaddr_in) ———————有對方號碼
3.發送/接收信息(sendto()/recvfrom())——————–發送/接收短信
4.關閉套接字close()——————————————-收發完畢
*******************服務器端***************************
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define N 32
//出錯處理宏函數
#define err_log(log)\
do{\
perror(log);\
exit(1);\
}while(0)
typedef struct sockaddr SA; //定義通用網絡信息結構體
int main(int argc, const char *argv[])
{
struct sockaddr_in serveraddr,clientaddr;
int sockfd;
char buf[N]={0};
socklen_t len=sizeof(SA);
//1.創建數據報套接字
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
err_log("fail to socket:");
}
//2.填充本地的網絡信息
serveraddr.sin_family=AF_INET; //ipv4網絡協議
serveraddr.sin_port=htons(atoi(argv[2]));//端口號
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);//ip地址
//3.綁定網絡信息
if(bind(sockfd,(SA*)&serveraddr,len)<0)
{
err_log("fail to bind:");
}
//4.發送和接收信息
while(1)
{
recvfrom(sockfd,buf,sizeof(buf),0,(SA*)&clientaddr,&len); //接收客戶端發來的數據
printf("%s\n",buf); //打印出接收的數據
memset(buf,0,sizeof(buf)); //清數據緩存區
strcpy(buf,"hello world"); //拷貝數據到數據緩存區
sendto(sockfd,buf,sizeof(buf),0,(SA*)&clientaddr,len); //發送數據包給客戶端
}
return 0;
}
*******************客戶端***************************
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#define N 32
//出錯處理宏函數
#define err_log(log)\
do{\
perror(log);\
exit(1);\
}while(0)
typedef struct sockaddr SA; //定義通用網絡信息結構體
int main(int argc, const char *argv[])
{
struct sockaddr_in serveraddr;
int sockfd;
char buf[N]={0};
socklen_t len=sizeof(SA);
//1.創建數據報套接字
if((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0)
{
err_log("fail to socket:");
}
//2.填充服務器端的網絡信息
serveraddr.sin_family=AF_INET; //ipv4網絡協議
serveraddr.sin_port=htons(atoi(argv[2]));//端口號
serveraddr.sin_addr.s_addr=inet_addr(argv[1]);//ip地址
//3.接收和發送信息
while(1)
{
fgets(buf,sizeof(buf),stdin); //標準輸入讀取數據
sendto(sockfd,buf,sizeof(buf),0,(SA*)&serveraddr,len); //發送數據包給服務器端(如果不關心客戶端的網絡信息最後的兩個參數可設置爲NULL)
bzero(buf,sizeof(buf)); //清空數據緩存區
recvfrom(sockfd,buf,sizeof(buf),0,(SA*)&serveraddr,&len); //從服務器端接收數據
puts(buf); //打印出接收的數據
}
return 0;
}