UDP 模型程序编写步骤
一、UDP基础模型
- step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -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");
- step 3:绑定 IP 和 Port 并判断
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (sockfd == -1)
{perror("bind failed");return -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);
- step 5:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if (ret == -1)
{perror("sendto failed");return -1;}
- step 6:关闭服务器
close(sockfd);
- step 7:检查头文件和变量是否添加和定义
- step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -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");
- step 3:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("sendto failed");return -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);
- step 5:关闭连接
close(sockfd);
- step 6:检查头文件和变量是否添加和定义
二、UDP 循环服务器模型
- step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -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");
- step 3:绑定 IP 和 Port 并判断
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (sockfd == -1)
{perror("bind failed");return -1;}
- step 4:设置循环接收数据
while (1)
{...}
- step 5:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -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);
- 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");
- step 8:关闭服务器
close(sockfd);
- step 9:检查头文件和变量是否添加和定义
- step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -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");
- step 3:设置循环发送并获取数据
while (1)
{fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
...}
- step 4:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("sendto failed");return -1;}
- step 5:设置退出循环条件
if (!strncmp("quit", buf, 4))
break;
- 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);
- step 7:关闭连接
close(sockfd);
- step 8:检查头文件和变量是否添加和定义
三、UDP 并发服务器模型
- step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -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");
- step 3:绑定 IP 和 Port 并判断
ret = bind(sockfd, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (sockfd == -1)
{perror("bind failed");return -1;}
- step 4:设置信号处理函数,防止僵尸进程
signal(SIGCHLD, SIG_IGN);
- step 5:设置循环接收数据
while (1)
{...}
- step 6:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -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);
- step 8:创建子进程并判断
pid = fork();
if (pid < 0)
{perror("fork failed");return -1}
- step 9:父进程继续
else if (pid > 0)
continue;
- step 10:子进程重新建立 socket 套接字并判断
else
{close(sockfd);
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1)
{perror("socket failed");return -1;}
- step 11:建立与客户端连接并判断
ret = connect(fd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
if (ret == -1)
{perror("connect failed");return -1;}
- step 12:设置子进程循环内发送数据并判断
while (1)
{ret = send(fd, buf, sizeof(buf), 0);
if (ret == -1)
{perror("send failed");return -1;}
printf("send successfully!\n");
- step 13:接收数据并判断
ret = recvfrom(sockfd, buf, sizeof(buf), (struct sockaddr *)&cliaddr, &addrlen);
if (ret == -1)
{perror("recvfrom failed");return -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);
- step 15:关闭客户端连接并退出子进程
close(fd);
exit(0);
- step 16:关闭服务器
close(sockfd);
- step 17:检查头文件和变量是否添加和定义
- step 1:创建 socket() 套接字接口并判断
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{perror("socket failed");return -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");
- step 3:设置循环发送并获取数据
while (1)
{fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
...}
- step 4:发送数据并判断
ret = sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *)&seraddr, sizeof(seraddr));
if (ret == -1)
{perror("sendto failed");return -1;}
- step 5:设置退出循环条件
if (!strncmp("quit", buf, 4))
break;
- 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);
- step 7:关闭连接
close(sockfd);
- step 8:检查头文件和变量是否添加和定义
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)