UDP 伺服器/客戶端
UDP:面向無連線,不安全,不可靠的,沒有狀態的傳輸協議
資料報:報文傳輸(目的方要麼整個報文收,要麼都不收到)
網路位元組序:網路採用統一的位元組順序
htons();將埠轉換指定的順序儲存
伺服器:接受使用者的請求並作響應Server
客戶端:向用戶發出請求,並等待響應 (知道 IP與埠)
UDP:C/S
客戶端 伺服器端
1、建立套接字 1、建立套接字
int socket(協議族,轉輸方式,預設0); int socket(協議族,轉輸方式,預設0);
2、傳送資訊 2、繫結套接字:將地址與埠
sendto bind
3、關閉套接字 3、收/發信息 recv / sendto 4、關閉套接字
地址型別:
1、strurct sockaddr
{
unsigned short sa_family;//地址族
char sa_data[14]; //地址和埠號
}; struct sockaddr_in
{
unsigned short sa_fafily;
unsigned short sa_port;//埠號
struct in_addr sin_addr;/*IP地址*/
unsigned char sin_zeron[8];//填充0(沒有意義)
};
注:先開啟伺服器
相關API:
1、建立套接字
socket
2、繫結套接字
bind
3、套接字地址型別:
struct sockaddr_in
{
};
4、轉換網張位元組序:
htons(short);
inet_addr(char* ip);
5、接收
recv(int ,void* ,size_t,int flag); //只接收內容
recvfrom(int,void*,size_t,int flog,struct sockaddr*,int*); //接收內容並接收IP 6、將網路位元組順序的IP地址轉換為字串(4段點分十進位制) char *inet_ntoa(struct in_addr in);
使用者層協議:雙方約定的規則
語法 語義
1#1 關機 注:在網路中,接收資訊的函式為阻塞函式(當沒有資訊來時,則阻塞。)
UDP 的伺服器端程式碼實現 , 實現了客戶端傳送訊息到服務端的功能 :
#include<stdio.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> //伺服器i:接受訊息 int main() { //建立套接字--UDP int fd=socket(AF_INET,SOCK_DGRAM,0); if(fd<0) { perror("socket fail"); return -1; } //繫結套接字:用於指明套接字繫結的網絡卡和埠號 struct sockaddr_in addr; //將地址結構體清空為0 bzero(&addr,sizeof(addr)); addr.sin_family =AF_INET; //指定該地址為IPV4 addr.sin_port =htons(7979);//埠 addr.sin_addr.s_addr =inet_addr("192.168.X.XXX");//本機的網絡卡IP地址為:XXX if(-1==bind(fd,(struct sockaddr*)&addr,sizeof(addr))) { perror("bind"); return -1; } //3收發訊息 char buf[100]=""; int ilen=-1; while((ilen=recv(fd,buf,100,0))>0) { buf[ilen]='\0'; printf("收到內容:%s\n",buf); } //4關閉訊息 close(fd); }
客戶端的程式碼實現 :
#include<stdio.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
int main()
{
//建立套接字:
int fd=socket(AF_INET,SOCK_DGRAM,0);
//繫結套接字:
//3傳送
struct sockaddr_in addr;
addr.sin_family =AF_INET;//地址
addr.sin_port =htons(7979);
addr.sin_addr.s_addr =inet_addr("192.168.X.XXX");
char buf[10]="";
scanf("%s",buf);
sendto(fd,buf,strlen(buf),0,(struct sockaddr*)&addr,sizeof(addr));
//關閉
close(fd);
}
UDP 的伺服器端程式碼實現 , 實現了客戶端傳送訊息到服務端 , 並且服務端返回訊息給客戶端 , 客戶端接收服務端訊息的功能 :
#include<arpa/inet.h>
#include<string.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
//伺服器:接受請求,並響應請求
int main()
{
//1建立套接字:
int fd=socket(AF_INET,SOCK_DGRAM,0);
if(fd<0)
{
perror("socket fail");
return -1;
}
//2繫結IP地址和埠號
struct sockaddr_in addr;
bzero(&addr,sizeof(addr));
addr.sin_family =AF_INET;
addr.sin_port =htons(7979);
addr.sin_addr.s_addr =INADDR_ANY;//本機地址
if(bind(fd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
perror("bind fail");
return -1;
}
//3收訊息
char buf[1024]="";
int ilen=0;
//地址型別
struct sockaddr_in caddr;
int addlen=sizeof(caddr);
while(1)
{
//ilen=recv(fd,buf,1023,0);
ilen=recvfrom(fd,buf,1023,0,(struct sockaddr*)&caddr,&addlen);
if(ilen<=0)//接收失敗
break;
//新增結束字元
buf[ilen]='\0';
printf("(%s:%d):%s\n",inet_ntoa(caddr.sin_addr),\
caddr.sin_port, \
buf); \
//解析字串:
if(strcmp(buf,"1#1")==0)
{
printf("客戶端讓我關機\n");
//返回狀態:
//發關送資訊
sendto(fd,"ok",2,0,(struct sockaddr*)&caddr,addlen);
}
}
//4關閉
close(fd);
}
客戶端的程式碼實現 :
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
//客戶端:
int main()
{
//1建立套接字
int fd=socket(AF_INET,SOCK_DGRAM,0);
char buf[100]="";
//[2繫結套接字:
int pid=fork();
if(pid>0)//父程序---傳送資訊
{
//3傳送
struct sockaddr_in addr;
addr.sin_family =AF_INET;//地址
addr.sin_port =htons(7979);
addr.sin_addr.s_addr =inet_addr("192.168.8.216");
while(1)
{
scanf("%s",buf);//等待輸入(阻塞)
if(sendto(fd,buf,strlen(buf),0,(struct sockaddr*)&addr,sizeof(addr))<=0)
break;//傳送失敗
}
//等待子程序結束
wait(NULL);
}
else if(pid==0)//子程序---接收資訊
{
int ilen=0;
while(1)
{
ilen=recv(fd,buf,99,0);
if(ilen<=0)
break;
//新增結尾
buf[ilen]='\0';
printf("收到:%s\n",buf);
}
}
else
{
perror("fork fail");
return -1;
}
//4關閉
close(fd);
}