栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

linux socket

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

linux socket

socket

根据进程在网络通信中使用的协议,可将socket通信方式分为两种:一种是面向连接、基于TCP协议的通信;另一种是面向无连接、基于UDP协议的通信

TCP

socket头文件
#include 
#include 
scocket
struct in_addr {
    uint32_t       s_addr;     
};
struct sockaddr_in {
    sa_family_t    sin_family; 
    in_port_t      sin_port;   
    struct in_addr sin_addr;   
};

大端和小端
大端字节序 - 低地址高字节,高地址低字节
小段字节序 - 低地址低字节,高地址高字节
TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。?
头文件 #include
uint32_t htonl(uint32_t hostint32)//主机字节转化为网络字节序
uint16_t htons(uint16_t hostint16)
uint32_t ntohl(uint32_t netint32)//网络字节序转化为主机字节序
unint16_t ntohs(uint16_t netint16)

IP地址转换
int inet_aton(const char *straddr,struct in_addr *addrp);
该函数的作用是将字符串形式的IP地址如“192.168.0.0.1”转换成网络能识别的形式
cha *inet_ntoa(struct in_addr inaddr)
该函数的作用是将网络格式的IP地址转换成字符串格式,通常用于接收方接收对方的IP地址并转换为字符串形式。
unsigned long inet_addr(const char* cp);
将一个ip地址字符串转换成一个整数值

  • 示例
//1. 服务器的ip为127.0.0.1,端口号1234
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");//本机ip环回地址

serv_addr.sin_port = htons(1234);

//2. 使用inet_aton
s_addr.sin_family=AF_INET;
s_addr.sin_port=htons(1234);
inet_aton("127.0.0.1", &s_addr.sin_addr);
bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));

//3. SIOCGIFADDR
    struct ifreq ifr;
    strcpy(ifr.ifr_name, net_deivce);
    ret = ioctl(fd, SIOCGIFADDR, &ifr);
    if(ret != 0){
        rtsp_printf(RTSP_ERR, "get net addr failed, ret = %d!n", ret);
        exit(-1);
    }
    sockaddr_in addr = ifr.ifr_addr;
    ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
listen
/**
 1. @brief 标记对应的socket处于监听状态。
 2. @param[in]sockfd : 要监听的socket描述字。
 3. @param[in]backlog: 相应socket可以排队的最大连接个数
 4. @return -1 失败
 5. @return 0 success
 6. /
//listen函数的第一个参数即为,第二个参数为。
int listen(int sockfd, int backlog);

从字面上看,其功能为使已经绑定的socket监听对应的客户端的状态,实际上为设置服务端可同时建立连接的最大数量。
参数说明

  1. sockfd
    socket文件描述符
  2. backlog

排队等待建立3次握手队列的长度。超过这个长度后的连接请求就被忽略。
这个长度还收到系统默认backlog的影响,如果大于默认长度,还是以默认长度为准。
默认长度的查询方法:
cat /proc/sys/net/ipv4/tcp_max_syn_backlog

示例

listen(fd, 50);
accept
/**
 * @brief 它提取侦听套接字 sockfd 的挂起连接队列上的第一个连接请求,创建一个新的连接套接字,
 * 并返回一个引用该套接字的新文件描述符。。
 * @param[in]sockfd : socket文件描述符。
 * @param[in]addr : 指向struct sockaddr *的指针,用于返回客户端的协议地址
 * @param[in]addrlen : 协议地址的长度
 * @return -1 失败
 * @return other 已连接的socket描述字
 * /
 int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

如果服务器调用accept()时还没有客户端的连接请求,就阻塞等待直到有客户端连接上来。
当传输层使用TCP协议时,服务器与客户端在创建连接前,会先经过“三次握手”机制测试连接,“三次握手”完成后,服务器调用accept函数处理连接请求,此时若还没有客户端的请求到达,便阻塞调用accpet的进程,知道客户端发出请求,切服务器中已创建的连接数未达到backlog,accpet才会返回。

示例

  fd_set  rfd;
  FD_ZERO(&rfd);
  FD_SET(rtsp->sockfd, &rfd);

  struct timeval tv;
  tv.tv_sec  = 1;
  tv.tv_usec = 0;
  ret = select(rtsp->sockfd + 1, &rfd, NULL, NULL, &tv);
  if(ret > 0) {
      if (FD_ISSET(rtsp->sockfd, &rfd)) {
          struct sockaddr_in remote;
          socklen_t len = sizeof(remote);
          U32 remote_fd = accept(rtsp->sockfd, (struct sockaddr *)&remote, &len);
          if (remote_fd > 0) {
      }
  }
connect sendto
/**
 * @brief 传输一个报文到另一个socket。
 * @param[in]sockfd : 已建好连线的socket,如果利用UDP协议则不需经过连线操作。
 * @param[in]buf: 数据地址
 * @param[in]len: 数据长度
 * @param[in]flags: 传输模式
 * @param[in]dest_addr: 目的地址
 *  @param[in]dest_addr: 目的地址结构体长度
 * @return -1 失败
 * @return other 发送的字节数
 * /
   ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                  const struct sockaddr *dest_addr, socklen_t addrlen);

sendto 和 sendmsg既可用于无连接的套接字,也可用于基于连接的套接字。除了套接字设置为非阻塞模式,调用将会阻塞直到数据被发送完。若sento()和sendmsg()函数向已连接的socket发送信息,则dest_addr 和addrlen必须为NULL

示例

struct sockaddr_in remote_addr;
memset(&remote_addr, 0, sizeof(remote_addr));
remote_addr.sin_family = AF_INET;
remote_addr.sin_addr.s_addr = inet_addr(rtp_net->client_ip); 
remote_addr.sin_port = htons(rtp_net->client_port);
return sendto(rtp_net->socket, buf, len, 0, 			
			(struct sockaddr *)&remote_addr, sizeof(remote_addr));
recvfrom
/**
 * @brief 由socket接受另一个主机的报文。
 * @param[in]sockfd : 已建好连线的socket,如果利用UDP协议则不需经过连线操作。
 * @param[in]buf: 数据地址
 * @param[in]len: 数据长度
 * @param[in]flags: 传输模式
 * @param[in]dest_addr: 目的地址
 *  @param[in]dest_addr: 目的地址结构体长度
 * @return -1 失败
 * @return other 接受的字节数
 * /
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                 struct sockaddr *src_addr, socklen_t *addrlen);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/939569.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号