前言

  之前曾经学习过一对回射客户/服务器程序的例子,不过那个是基于TCP协议的。本文将讲解另一对回射客户/服务器程序,该程序基于UDP协议。由于使用的协议不同,因此编写出的程序也有本质上的区别,应将它们对比来进行理解。

通信框架

  

服务器端

 #include    "unp.h"

 int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr; // 创建UDP套接字
sockfd = Socket(AF_INET, SOCK_DGRAM, ); 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));
}
 #include    "unp.h"

 void
dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg[MAXLINE]; for ( ; ; ) {
len = clilen;
// 接收数据
n = Recvfrom(sockfd, mesg, MAXLINE, , pcliaddr, &len); // 回射数据
Sendto(sockfd, mesg, n, , pcliaddr, len);
}
}

客户端

 #include    "unp.h"

 int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr; if (argc != )
err_quit("usage: udpcli <IPaddress>"); bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
Inet_pton(AF_INET, argv[], &servaddr.sin_addr); // 创建UDP套接字
sockfd = Socket(AF_INET, SOCK_DGRAM, ); dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr)); exit();
}
 #include    "unp.h"

 void
dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
int n;
char sendline[MAXLINE], recvline[MAXLINE + ];
socklen_t len;
struct sockaddr *preply_addr; preply_addr = Malloc(servlen); while (Fgets(sendline, MAXLINE, fp) != NULL) { // 往服务器发送数据
Sendto(sockfd, sendline, strlen(sendline), , pservaddr, servlen); len = servlen;
n = Recvfrom(sockfd, recvline, MAXLINE, , preply_addr, &len);
// 不接收非指定服务器的数据
if (len != servlen || memcmp(pservaddr, preply_addr, len) != ) {
printf("reply from %s (ignored)\n",
Sock_ntop(preply_addr, len));
continue;
} // 将回射结果打印给用户
recvline[n] = ; /* null terminate */
Fputs(recvline, stdout);
}
}

小结

  1. UDP的机制比起TCP来说,简单多了。但也因此缺少了重传机制,验证相应是否来自对端等等可靠性相关的性质。

  2. 只有被 connect 后的UDP套接字才能收到异常信息。

最新文章

  1. POJ3061 尺取法
  2. 【C-循环结构】
  3. SSIS的CheckPoint用法
  4. swift学习笔记之-高级运算符
  5. bzoj2219: 数论之神
  6. 【final】站立会议---11.28
  7. php获取远程文件大小
  8. wpa_supplicant 使用
  9. HDU2206 IP的计算 【经典题】
  10. dede 转 帝国
  11. C语言博客作业字符数组
  12. 完美解决ubuntu Desktop 16.04 中文版firefox在非root用户不能正常启动的问题
  13. 【ZJOI2007】粒子运动
  14. 立个Flag不学好PHP誓不罢休
  15. Linux之nginx服务
  16. 高性能Javascript(1)
  17. PAT-GPLT训练集 L2-001 紧急救援(最短路)
  18. Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)成功烧录方法
  19. WPF Demo15 MVVM
  20. input,textarea在ios和Android上阴影和边框的处理方法(在移动端)

热门文章

  1. es6总结(七)--proxy &amp; reflect
  2. es6总结(四)--对象
  3. 【kindeditor】KindEditor获取多个textarea文本框的值并判断非空
  4. 一简单c++程序之反汇编
  5. .NET中JSON的序列化和反序列化的几种方式
  6. Unity3D Shader 入门之简单案例的实现(通过法线实现颜色变化)
  7. 采集网站特殊文件Meta信息
  8. c实现的trim函数
  9. loj #110. 乘法逆元
  10. 【APIO2016】Gap