Linux IPC udp/ip socket 编程

Linux IPC udp/ip socket 编程

#include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> //服务器: socket() //创建socket struct sockaddr_in //准备通信地址 bind() //绑定socket和addr sendto()/recvfrom //进行通信 close() //关闭socket //客户端: socket() //创建socket: //准备通信地址:服务器的地址 sendto()/recv() //进行通信: close() //关闭socket: socket() //创建网络端点,返回socket文件描述符,失败返回-1设errno int socket(int domain, int type, int protocol);

domain :协议族(protocol family)(网络通讯(IP)还是本地通讯(xxx.socket))

AF_INET用于实现给予ipv4网络协议的网络协议
type :协议(TCP还是UDP)

SOCK_DGRAM //数据报套接字, 实现包括但不限于UDP协议, which is不可靠,无连接的数据报通信方
protocol: 特殊协议, 一般给0

准备通信地址: struct sockaddr{ //主要用于函数的形参类型, 很少定义结构体变量使用, 叫做通用的通信地址类型//$man bind sa_family_t sa_family; char sa_data[14]; } struct sockaddr_in{ //准备网络通信的通信地址 //$man in.h sa_family_t sin_family; //协议族, 就是socket()的domain的AF_INET in_port_t sin_port; //端口号 struct in_addr sin_addr; //IP地址, //当前网段的最大ip地址是广播地址,即,xxx.xxx.xxx.255。 //255.255.255.255在所有网段都是广播地址 } struct in_addr{ in_addr_t s_addr; //整数类型的IP地址 } bind() //把通信地址和socket文件描述符绑定,用在服务器端,成功返回0,失败返回-1设errno int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

sockfd: socket文件的fd(returned by socket())
addr: 需要强制类型转换成socketaddr_un或soketaddr_in, 参见上
addrlen: 通信地址的大小, 使用sizeof();

sendto() //向指定的socket和相应的地址发送消息,成功返回实际发送数据的大小,失败返回-1设errno ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

dest_addr:目标地址(收件人信息)
addrlen: 目标地址的大小

ANote

send(sockfd, buf, len, flags);等价于 sendto(sockfd, buf, len, flags, NULL, 0);

recv()/ send()表示通过sockfd收发数据, 因为tcp下, 收发之前sockfd已经和相应的地址连接了,所以不需要指定收发谁的/给谁, 但是udp因为收发时没有连接, 所以需要指定

recvfrom() //从指定的socket和相应的地址接受消息,并提供来电显示的功能,成功返回实际接收的数据大小,失败返回-1设errno ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);

src_addr: 结构体指针, 用于保存数据发送方的通信地址
addrlen: 指针类型, 用于保存发送方的地址大小

Note:

recv(sockfd, buf, len, flags); 等价于 recvfrom(sockfd, buf, len, flags, NULL, 0);

accept() and recvfrom() 后面的参数是用来提供来电显示的

一个server对应多个client

server可以不知道client的地址, 但是client得知道server的地址

send data 一定要知道对方地址

receive data不需要知道对方地址

TCP/IP的socket都是SOCK_STREAM的,全程连接,通过socket就能找到对方地址, send data的话,直接丢给socket就行

UDP/IP的socket是SOCK_DGRAM的,不全程连接,不能通过socket找到对方,send data的话,server中需要使用recvfrom()来知道client的地址, 所以肯定要sendto();client本来就知道server的地址, 直接sendto()

recvfrom()的唯一意义就是在udp-server中配合sendto()使用

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/57b5faea79820c6fd94e344ba390e19e.html