Linux socket 编程 UDP
创始人
2024-01-18 12:54:46

套接字:操作系统向上层提供的用于实现网络通信的统称

网络通信其实本质上就是两台主机之间的通信其中一段是客户端,另一端是服务器

        客户端:用户的一端,客户端是主动发出请求的一端

        服务端:针对用户请求提供服务的一端,服务器是被动接收的一端

传输层协议:TCP UDP

        TCP :传输控制协议,面向连接,可靠传输,面向字节流

        应用于安全性要求大于实时性要求的场景 例如文件传输

        UDP:用户数据包协议,无连接,不可靠,面向数据报

        应用于对实时性要求大于安全性要求的场景 例如视频音频

UDP通信程序编写:

客户端:

        1.创建套接字

        2.为套接字绑定地址信息

        客户端不推荐绑定指定地址

                1.绑定之后,程序只能在启动一个

                2.客户端并不需要固定使用某个地址

        3.向服务器发送数据

                发送数据之前若socket没有绑定指定的地址信息,系统会选择合适的地址信息进行绑定

        4.接受数据

        5.关闭套接字

服务器

        1.创建套接字

                在内核创建socket 结构体,将进程跟网卡关联起来

        2.为套接字绑定指定地址信息

                给创建套接字socket结构体描述源端地址信息

                1.告诉系统,网卡收到哪个数据应该交给我

                2.当发送数据的时候使用绑定的地址信息作为源端地址信息

        3.接受数据

                从socket的接受缓冲区取出数据

        4.发送数据

                把要发送的数据放到发送缓冲区

        5.关闭套接字

UDP要用到的套接字接口介绍

socket();

函数原型:int socket(int domain, int type, int protocol);

参数介绍:

domain:地址域类型  ,指明使用的协议族。常用的协议族有AF_INET、AF_INET6,协议族决定了socket的地址类型,在通信中必须采用对应的地址,如AF_INET决定了要用ipv4地址(32位的)与端口号(16位的)的组合

type:指明socket类型 SOCK_STREAM面向连接,面向字节流,可靠传输。TCP类型

SOCK_DGRAM,无连接,面向数据报,不可靠传输。UDP类型

protocol:协议类型 0是由系统自动选择的 IPRPROTO_TCP,IPRPROTO_UDP

返回值:成功返回套接字描述符,失败返回-1

bind ();

函数原型:int bind (int sockefd , const struct socketaddr * addr , socetlen_t addrlen);

参数介绍:

socketfd:socket();函数返回的描述符将socket绑定到指定的IP和端口上面,当socket返回描述符时,只是存在于其协议族中并没有实际分配协议地址。

addr:要绑定的地址信息 ipv4 是struct sockaddr_in     ipv6 是struct sockaddr_in6

addrler:地址信息长度,通常设置为sizeof(struct sockaddr)。

struct socketaddr_in

{

    sin_family;

    sin_port;

    sin_addr.s_addr;

}

返回值 0是成功 -1代表出错

sendto();

函数原型:sszie_t(int socketfd ,const void *buf,  size_t. len ,int flags,const struct sockaddr*dest_addr , socklen_t addrlen );

参数介绍:

socketfd:发送套接字的描述符 因为是用于非可靠链接UDP的数据发送,不用先建立连接,只需要给出目的协议地址就好了。

buf:要发送的数据空间首地址,因为UDP没有真正的发送缓冲区,因为是不可靠链接,不必保存应用里面的数据拷贝,因为应用进程中的数据沿协议向下传递的过程中,会以某种形式拷贝到内核缓冲区,当数据链路层把数据发出去的时候,内核缓冲区就会把数据删除,所以他不需要一个发送缓冲区

len:要发送的数据长度

flag:选项标志 0 默认为阻塞发送

dest_addr:对端地址信息

addrlen:地址信息长度

返回值:返回成功是实际发送的数据字节长度;失败返回-1;

recvfrom();

函数原型:ssize_t(int sockfd , void *buf , size_t len, int flags, struct sockaddr * src_addr , socklen_t * addrlen);

参数介绍:

sockfd:套接字描述符

buf:一块空间的首地址,用于存放从内核获取到的数据

len:要获取的数据长度

flag:默认0-阻塞接受

src_addr:当前接受的数据的发送方的地址信息

*addrlen:这是一个输入输出型参数,指定想要多长地址,返回实际长度

返回值:成功返回实际接收到的数据长度,失败返回-1;

函数实现

服务器

udp_srv.c

#include
#include
#include
#include//struct sockaddr_in 结构
#include
#include//字节序转换接口文件
#include//socket接口文件int main()
{//实现udp 服务器//创建套接字int sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if(sockfd < 0){perror("socket error !");return -1;}//绑定地址信息bindstruct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(9090);addr.sin_addr.s_addr = inet_addr("10.0.8.12");socklen_t len = sizeof(struct sockaddr_in);int ret = bind(sockfd,(struct sockaddr* ) &addr ,len );if(ret < 0){close(sockfd);perror("bind error !");return -1;}while (1){//接受数据char buf[1024] = {0};struct sockaddr_in cliaddr;ret = recvfrom(sockfd,buf,1023,0,(struct sockaddr *) &cliaddr,&len);if(ret < 0){perror("recvfrom error !"); close(sockfd);return -1;}printf("客户端: %s : %d 说: %s \n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port),buf);//发送数据printf("服务器: ");fflush(stdout);char data [1024] = {0};fgets(data,1023,stdin);ret = sendto(sockfd,data,strlen(data),0,(struct sockaddr*)&cliaddr,len);if(ret < 0){perror("sento error !");close (sockfd);return -1;}}// 关闭套接字close(sockfd);return 0;
}

udp_scoket.h

//封装一个udpsocket类
//通过实例化对象来调用成员函数完成客户端服务器搭建
#include
#include
#include
#include
#include
#include
using namespace std;
class UdpSocket{private:int _sockfd;public:UdpSocket():_sockfd(-1){}~UdpSocket(){if(_sockfd != -1){close(_sockfd);}}bool Socket(){_sockfd = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);if(_sockfd < 0){perror("socket error !");return false;}return true;}bool Bind(const string &ip,uint16_t port){struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);int ret;ret = bind(_sockfd,(struct sockaddr*)&addr,len);if(ret < 0){perror("bind error !");return false;}return true;}bool Send(const string &data,const string &ip,uint16_t port){struct sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr(ip.c_str());socklen_t len = sizeof(struct sockaddr_in);int ret;ret = sendto(_sockfd,data.c_str(),data.size(),0,(struct sockaddr*) &addr,len);if(ret < 0){perror("sendto error");return false;}return true;}bool Recv(string *buf, string *ip = NULL,uint16_t *port = NULL){struct sockaddr_in addr;socklen_t len = sizeof(struct sockaddr_in);char temp [4096] = {0};int ret;ret = recvfrom(_sockfd,temp,4096,0,(struct sockaddr *)&addr,&len);if(ret < 0){perror ("recvfrom error !");return false;}if(ip != NULL){*ip = inet_ntoa(addr.sin_addr);}if(port != NULL){*port = ntohs(addr.sin_port);}*buf = temp;return true;}bool Close(){if(_sockfd != -1){close(_sockfd);}return true;}
};

udp_cli.cpp

#include"udp_socket.hpp"
using namespace std;#define CHECK_RES(q) if((q)==false) {return -1;}
int main(int argc,char *argv[])
{if(argc != 3){cout<< "Usage : ./udp_cli 10.0.8.12 9090" << endl;cout << "Server Address !" << endl;return -1;}string srv_ip = argv[1];int srv_port = stoi(argv[2]);UdpSocket sock;CHECK_RES(sock.Socket());while(1){cout << "客户端 : " ;fflush(stdout);string buf;cin >> buf;CHECK_RES(sock.Send(buf,srv_ip,srv_port));buf.clear();CHECK_RES(sock.Recv(&buf));cout << "服务器 : " << buf << endl;}CHECK_RES(sock.Close());return 0;
}

 

 

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
苁蓉的食用方法 鲜苁蓉的吃法有... 肉苁蓉号称“温而不热,补而不峻,暖而不燥,滑而不泄,故有从容之名。”历来也是传统药食同源的滋补佳品。...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
阳澄湖在哪里哪个省的 阳澄湖是... 点击题目下方苏州生活指南有用 有趣 有态度近期的阳澄湖度很高,3月24日,央视二套《第一时间》直播连...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...