1、UDP协议
TCP/UDP比较:
TCP:面向连接可靠的数据包传递
优点:稳定:数据----回执机制 速率 流量----“滑动窗口”
缺点:效率低
使用场景:大文件、重要文件传输
UDP:面向无连接的不可靠报文传递---完全不弥补
缺点:不稳定:数据、速率、流量
优点:效率高、速度快
使用场景:对实时性要求较高,视频会议、视频电话、广播
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
int n=220*1024
setsockopt(sockfd, SOL_SOCKET,SO_RCVBUF, &n,sizeof(n));
通过增加接收缓冲区大小,减少丢包率
udp不需要listen,因为不需要三次握手
服务器:
读数据:阻塞等待数据
#include <sys/types.h>
#include <sys/socket.h>
//ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);
//ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
写数据:
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
客户端:调用sendto()和recvfron();
2、广播:IP:32位
192.168.42.255广播地址
192.168.42.1网关地址
要利用下面的函数给套接字开放广播权限
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
服务器要设定客户端的端口号
客户端要绑定相同的端口,绑定的IP写’0.0.0.0‘
3、组播(多播)
组播组可以是临时的,也可以是永久的
239.0.0.1~239.0.0.255
网卡编号:
#include <net/if.h>
unsigned int if_nametoindex(const char *ifname);
char *if_indextoname(unsigned int ifindex, char *ifname);
struct ip_mreqn {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_address; /* local IP address of interface */
int imr_ifindex; /* Interface index */
};
设置组播权限:
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
!!setsockopt:1、端口复用2、设置缓冲区大小3、开放广播权限4、开放组播权限5、加入组播组
4、本地套接字(domain):稳定性最好:全双工
struct sockaddr_un {
__kernel_sa_family_t sun_family; /* AF_UNIX */
char sun_path[UNIX_PATH_MAX]; /* pathname *///文件名(含路径)
}
不需要端口和IP,不用TCP/UDP
unix_socket = socket(AF_UNIX, type, 0);
调用unlink,确保套接字文件名不存在,然后bind才能创建该文件
#include <unistd.h>
int unlink(const char *pathname);
bind的第三个参数传文件名大小:用offsetof:宏函数
服务器设计:
lfd=socket(AF_UNIX,SOCK_STREAM,0);
struct sockaddr_un serv_addr;
serv_addr.sun_family=AF_UNIX;
strcpy(serv_addr.sun_path,"mysocket")
int len=offsetof(struct sockaddr_un,sun_path)+strlen(serv_addr.sun_path);//计算结构体实际大小
unlink("mysocket");//确保没有重复的文件名
bind(lfd,(struct sockaddr*)&serv_addr,len);
struct sockaddr_un clie_addr;
len=sizeof(clie_addr);
cfd=accept(lfd,(struct sockaddr*)&clie_addr,(socklen_t*)&len);
len-=offset(struct sockaddr_un,sun_path);//得到文件名长度
//clie_addr.sun_path[len]='\0';//确保打印的时候不会乱码
len不能直接用sizeof(sockaddr_un)因为这个结构体大小总共是110B,但是文件名通常占不满,所以要用宏函数offsetof()
5、第三方库
libevent---->libev升级版
开源库的一般使用方法:1、./configure ---->check 当前主机是否适合安装 ------makefile
2、make
3、sudo make install
README/README.md