网络通信2—UDP 模型程序编写步骤(参照 Ubuntu 16.04 版本)

UDP 模型程序编写步骤

一、UDP基础模型
  • 服务器流程
  1. step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:绑定 IP 和 Port 并判断
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (sockfd == -1)
{perror("bind failed");return -1;}
  1. step 4:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
printf("recv from %s: %d, content: %s\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buf);
  1. step 5:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if (ret == -1)
{perror("sendto failed");return -1;}
  1. step 6:关闭服务器
close(sockfd);
  1. step 7:检查头文件和变量是否添加和定义
  • 客户端流程
  1. step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("sendto failed");return -1;}
  1. step 4:接收数据并判断输出
ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
printf("recv from %s: %d\ncontent: %s\n", inet_ntoa(seraddr.sin_addr), ntohs(seraddr.sin_port), buf);
  1. step 5:关闭连接
close(sockfd);
  1. step 6:检查头文件和变量是否添加和定义
二、UDP 循环服务器模型
  • 服务器流程
  1. step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:绑定 IP 和 Port 并判断
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (sockfd == -1)
{perror("bind failed");return -1;}
  1. step 4:设置循环接收数据
while (1)
{...}
  1. step 5:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
  1. step 6:设置跳出循环条件
if (!strncmp("quit", buf, 4)
{printf("client IP: %s Port: %d is disconnected\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port);continue;}
printf("recv from %s: %d, content: %s\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buf);
  1. step 7:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if (ret == -1)
{perror("sendto failed");return -1;}
printf("send successfully!\n");
  1. step 8:关闭服务器
close(sockfd);
  1. step 9:检查头文件和变量是否添加和定义
  • 客户端流程
  1. step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:设置循环发送并获取数据
while (1)
{fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
...}
  1. step 4:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("sendto failed");return -1;}
  1. step 5:设置退出循环条件
if (!strncmp("quit", buf, 4))
break;
  1. step 6:接收数据并判断输出
ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
printf("recv from %s: %d\ncontent: %s\n", inet_ntoa(seraddr.sin_addr), ntohs(seraddr.sin_port), buf);
  1. step 7:关闭连接
close(sockfd);
  1. step 8:检查头文件和变量是否添加和定义
三、UDP 并发服务器模型
  • 服务器流程
  1. step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:绑定 IP 和 Port 并判断
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (sockfd == -1)
{perror("bind failed");return -1;}
  1. step 4:设置信号处理函数,防止僵尸进程
signal(SIGCHLD, SIG_IGN);
  1. step 5:设置循环接收数据
while (1)
{...}
  1. step 6:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
  1. step 7:设置跳出循环条件
if (!strncmp("quit", buf, 4)
{printf("client IP: %s Port: %d is disconnected\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port);continue;}
printf("recv from %s: %d, content: %s\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buf);
  1. step 8:创建子进程并判断
pid = fork();
if (pid < 0)
{perror("fork failed");return -1}
  1. step 9:父进程继续
else if (pid > 0)
continue;
  1. step 10:子进程重新建立 socket 套接字并判断
else
{close(sockfd);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
{perror("socket failed");return -1;}
  1. step 11:建立与客户端连接并判断
ret = connect(fd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if (ret == -1)
{perror("connect failed");return -1;}
  1. step 12:设置子进程循环内发送数据并判断
while (1)
{ret = send(fd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send failed");return -1;}
printf("send successfully!\n");
  1. step 13:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
  1. step 14:设置跳出循环条件
if (!strncmp("quit", buf, 4)
{printf("client IP: %s Port: %d is disconnected\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port);break;}
printf("recv from %s: %d, content: %s\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port), buf);
  1. step 15:关闭客户端连接并退出子进程
close(fd);
exit(0);
  1. step 16:关闭服务器
close(sockfd);
  1. step 17:检查头文件和变量是否添加和定义
  • 客户端流程(同循环客户端流程)
  1. step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -1;}
  1. step 2:设置服务器 IP 和 Port
memset(&seraddr, 0, sizeof(seraddr));
seraddr.sin_family = AF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
  1. step 3:设置循环发送并获取数据
while (1)
{fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
...}
  1. step 4:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("sendto failed");return -1;}
  1. step 5:设置退出循环条件
if (!strncmp("quit", buf, 4))
break;
  1. step 6:接收数据并判断输出
ret = recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -1;}
printf("recv from %s: %d\ncontent: %s\n", inet_ntoa(seraddr.sin_addr), ntohs(seraddr.sin_port), buf);
  1. step 7:关闭连接
close(sockfd);
  1. step 8:检查头文件和变量是否添加和定义

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值