首页 » PHP教程 » phpudpsocket技巧_Linux C Socket UDP编程详解及实例分享

phpudpsocket技巧_Linux C Socket UDP编程详解及实例分享

访客 2024-11-03 0

扫一扫用手机浏览

文章目录 [+]

UDP协议的做事器端流程

做事器流程紧张分为下述6个部分,即建立套接字、设置套接字地址参数、进行端口绑定、吸收数据、发送数据、关闭套接字等。

phpudpsocket技巧_Linux C Socket UDP编程详解及实例分享

(1)建立套接字文件描述符,利用函数socket(),天生套接字文件描述符。

phpudpsocket技巧_Linux C Socket UDP编程详解及实例分享
(图片来自网络侵删)

(2)设置做事器地址和侦听端口,初始化要绑定的网络地址构造。

(3)绑定侦听端口,利用bind()函数,将套接字文件描述符和一个地址类型变量进行绑定。

(4)吸收客户真个数据,利用recvfrom()函数吸收客户真个网络数据。

(5)向客户端发送数据,利用sendto()函数向做事器主机发送数据。

(6)关闭套接字,利用close()函数开释资源。
UDP协议的客户端流程

UDP协议的客户端流程

UDP协议的客户端流程分为套接字建立、设置目的地址和端口、向做事器发送数据、从做事器吸收数据、关闭套接字等5个部分。
流程如下:

(1)建立套接字文件描述符,socket();

(2)设置做事器地址和端口,struct sockaddr;

(3)向做事器发送数据,sendto();

(4)吸收做事器的数据,recvfrom();

(5)关闭套接字,close()。

UDP编程流程

2、干系函数

(1) int socket(AF_INET, SOCK_DGRAM, 0);

创建udp socket,返回套接字描述符,UDP协议建立套接字的办法同TCP办法一样,利用socket()函数,只不过协议的类型利用SOCK_DGRAM,而不是SOCK_STREAM。

(2) int sendto(int sockfd, const void data, int data_len, unsigned int flags, struct sockaddr remaddr,sock_lenremaddr_len)

功能:基于UDP发送数据报,返回实际发送的数据长度,出错时返回-1

参数解释:

sockfd:套接字描述符

data:指向要发送数据的指针

data_len:数据长度

flags:常日为0

remaddr:远端地址:IP地址和端口号

remaddr_len:地址长度

(3) int recvfrom(int sockfd, void buf,int buf_len,unsigned int flags,struct sockaddr from,sock_len fromlen);

功能:从UDP吸收数据,返回实际吸收的字节数,失落败时返回-1

参数解释:

Sockfd:套接字描述符

buf:指向内存块的指针

buf_len:内存块大小,以字节为单位

flags:一样平常为0

from:远真个地址,IP地址和端口号

fromlen:远端地址长度

(4) ssize_t recv(int s, voidbuf,size_t len, int flags);

连接的UDP可调用recv从做事器读取数据。

ssize_tsend(int s, const voidbuf, size_t len, int flags);

连接的UDP可调用send向做事器发送数据。

3、UDPSocket客户做事器通信实例

下面依照通信流程,我们来实现一个UDP回射客户/做事器。

UDP回射客户/做事器流程

做事器代码:

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<errno.h>#include<sys/types.h>#include<sys/socket.h>#include<netinet/in.h>#include<string.h> #define MYPORT 8887 #define ERR_EXIT(m) \ do { \ perror(m); \ exit(EXIT_FAILURE); \ } while (0) void echo_ser(int sock){ char recvbuf[1024] = {0}; struct sockaddr_in peeraddr; socklen_t peerlen; int n; while (1) { peerlen = sizeof(peeraddr); memset(recvbuf, 0, sizeof(recvbuf)); n = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, (struct sockaddr )&peeraddr, &peerlen); if (n <= 0) { if (errno == EINTR) continue; ERR_EXIT("recvfrom error"); } else if(n > 0) { printf("吸收到的数据:%s\n",recvbuf); sendto(sock, recvbuf, n, 0, (struct sockaddr )&peeraddr, peerlen); printf("回送的数据:%s\n",recvbuf); } } close(sock);} int main(void){ int sock; if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) ERR_EXIT("socket error"); struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MYPORT); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); printf("监听%d端口\n",MYPORT); if (bind(sock, (struct sockaddr )&servaddr, sizeof(servaddr)) < 0) ERR_EXIT("bind error"); echo_ser(sock); return 0;}

客户端代码:

#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h> #define MYPORT 8887char SERVERIP = "127.0.0.1"; #define ERR_EXIT(m) \ do \{ \ perror(m); \ exit(EXIT_FAILURE); \ } while(0) void echo_cli(int sock){ struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(MYPORT); servaddr.sin_addr.s_addr = inet_addr(SERVERIP); int ret; char sendbuf[1024] = {0}; char recvbuf[1024] = {0}; while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL) { printf("向做事器发送:%s\n",sendbuf); sendto(sock, sendbuf, strlen(sendbuf), 0, (struct sockaddr )&servaddr, sizeof(servaddr)); ret = recvfrom(sock, recvbuf, sizeof(recvbuf), 0, NULL, NULL); if (ret == -1) { if (errno == EINTR) continue; ERR_EXIT("recvfrom"); } printf("从做事器吸收:%s\n",recvbuf); memset(sendbuf, 0, sizeof(sendbuf)); memset(recvbuf, 0, sizeof(recvbuf)); } close(sock); } int main(void){ int sock; if ((sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) ERR_EXIT("socket"); echo_cli(sock); return 0;}

实验结果:

UDP编程把稳:

1、UDP报文可能会丢失、重复

2、UDP报文可能会乱序

3、UDP缺少流量掌握

4、UDP协议数据报文截断

5、recvfrom返回0,不代表连接关闭,由于udp是无连接的。

6、ICMP异步缺点

7、UDP connect

8、UDP外出接口的确定

9、太大的UDP包可能涌现的问题

由于UDP不须要掩护连接,程序逻辑大略了很多,但是UDP协议是不可靠的,实际上有很多担保通讯可靠性的机制须要在运用层实现,即123点所提到的。
比如 如果发送端速率较快,而吸收端较慢,很可能会产生 ICMPSource Quench Error,丢弃一些数据包。

须要C/C++ Linux做事器架构师学习资料私信“资料”(资料包括C/C++,Linux,golang技能,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,ffmpeg等),免费分享

相关文章

执业药师试卷代码解码药师职业发展之路

执业药师在药品质量管理、用药安全等方面发挥着越来越重要的作用。而执业药师考试,作为进入药师行业的重要门槛,其试卷代码更是成为了药师...

PHP教程 2025-02-18 阅读0 评论0

心灵代码主题曲唤醒灵魂深处的共鸣

音乐,作为一种独特的艺术形式,自古以来就承载着人类情感的表达与传递。心灵代码主题曲,以其独特的旋律和歌词,唤醒了无数人的灵魂深处,...

PHP教程 2025-02-18 阅读0 评论0

探寻福建各市车牌代码背后的文化内涵

福建省,地处我国东南沿海,拥有悠久的历史和丰富的文化底蕴。在这片充满魅力的土地上,诞生了许多具有代表性的城市,每个城市都有自己独特...

PHP教程 2025-02-18 阅读0 评论0

探寻河北唐山历史与现代交融的城市之光

河北省唐山市,一座地处渤海之滨,拥有悠久历史和独特文化的城市。这里既是古丝绸之路的起点,也是中国近代工业的发源地。如今,唐山正以崭...

PHP教程 2025-02-18 阅读0 评论0