网络编程 常用调试测试工具 网络信息检索函数 OOB带外数据和广播、组播 UNIX域套接字

网络编程第六天

一、常用调试测试工具

使用telnet测试TCP服务器端
使用lsof
使用tcpdump
使用netstat
使用sniffer
使用wireshark
Chariot
…
SmartBit—硬件

二、网络信息检索函数

gethostname() 获得主机名
getpeername() 获得与套接口相连的远程协议地址
getsockname() 获得本地套接口协议地址
gethostbyname() 根据主机名取得主机信息 
gethostbyaddr() 根据主机地址取得主机信息
getprotobyname() 根据协议名取得主机协议信息
getprotobynumber() 根据协议号取得主机协议信息
getservbyname() 根据服务名取得相关服务信息
getservbyport() 根据端口号取得相关服务信息

三、网络属性设置

getsockopt和setsockopt 

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)
level指定控制套接字的层次.可以取三种值: 
1)SOL_SOCKET:通用套接字选项. 
2)IPPROTO_IP:IP选项. 
3)IPPROTO_TCP:TCP选项. 
optname指定控制的方式(选项的名称),我们下面详细解释 
optval获得或者是设置套接字选项.根据选项名称的数据类型进行转换

四、网络超时

设置socket的属性 SO_RCVTIMEO

参考代码如下
    struct timeval  tv;

     tv.tv_sec = 5;   //  设置5秒时间
     tv.tv_usec = 0;

     setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO,  &tv,  
                       sizeof(tv));   //  设置接收超时
      recv() / recvfrom()    //   从socket读取数据

用select检测socket是否’ready’

参考代码如下
    struct fd_set rdfs;
    struct timeval  tv = {5 , 0};   // 设置5秒时间

    FD_ZERO(&rdfs);
    FD_SET(sockfd, &rdfs);

    if (select(sockfd+1, &rdfs, NULL, NULL, &tv) > 0)   // socket就绪
    {
          recv() /  recvfrom()    //  从socket读取数据
    }
设置定时器(timer), 捕捉SIGALRM信号

参考代码如下
    void  handler(int signo)     {   return;  }

      struct sigaction  act;
      sigaction(SIGALRM, NULL, &act);
      act.sa_handler = handler;
      act.sa_flags &= ~SA_RESTART;
      sigaction(SIGALRM, &act, NULL);
      alarm(5);
      if (recv(,,,) < 0) ……

五、OOB带外数据和广播、组播

TCP 上没有真正意义上的“带外数据” 
TCP 由 “紧急模式”的方法来传 
发送方:设置URG选项
接收方:收到包含URG的TCP数据设置带外数据标志指针->指针指向带外数据位置
发送:
 send(int sockfd, void *buf, int len, int flags);
 其中flags设置为MSG_OOB
接收:
Recv(int sockfd, void *buf, int len, int flags);
其中flags设置为MSG_OOB

广播

前面介绍的数据包发送方式只有一个接受方,称为单播

如果同时发给局域网中的所有主机,称为广播

只有用户数据报(使用UDP协议)套接字才能广播

广播地址
以192.168.1.0 (255.255.255.0) 网段为例,最大的主机地址192.168.1.255代表该网段的广播地址
发到该地址的数据包被所有的主机接收
255.255.255.255在所有网段中都代表广播地址
创建用户数据报套接字

缺省创建的套接字不允许广播数据包,需要设置属性
setsockopt可以设置套接字属性

接收方地址指定为广播地址

指定端口信息

发送数据包
int  setsockopt(int  s,  int level,  int  optname, const void *optval, socklen_t  optlen);
头文件:<sys/socket.h>
level : 选项级别(例如SOL_SOCKET)
optname : 选项名(例如SO_BROADCAST)
optval : 存放选项值的缓冲区的地址
optlen : 缓冲区长度
返回值:成功返回0   失败返回-1并设置errno

sockfd = socket(,,);
……
int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
……
sendto(;;;;;);

组播

单播方式只能发给一个接收方。

广播方式发给所有的主机。过多的广播会大量占用网络带宽,造成广播风暴,影响正常的通信。

组播(又称为多播)是一种折中的方式。只有加入某个多播组的主机才能收到数据。

多播方式既可以发给多个主机,又能避免象广播那样带来过多的负载(每台主机要到传输层才能判断广播包是否要处理)

网络地址

A类地址
第1字节为网络地址,其他3个字节为主机地址。第1字节的最高位固定为0
1.0.0.1 – 126.255.255.255
B类地址
第1字节和第2字节是网络地址,其他2个字节是主机地址。第1字节的前两位固定为10
128.0.0.1 – 191.255.255.255
C类地址
前3个字节是网络地址,最后1个字节是主机地址。第1字节的前3位固定为110
192.0.0.1 – 223.255.255.255
D类地址(组播地址)
不分网络地址和主机地址,第1字节的前4位固定为1110
224.0.0.1 – 239.255.255.255

在这里插入图片描述

struct ip_mreq
{
     struct  in_addr  imr_multiaddr;
     struct  in_addr  imr_interface;
};
struct  ip_mreq  mreq;
bzero(&mreq, sizeof(mreq));
mreq.imr_multiaddr.s_addr = inet_addr(“224.10.10.1”);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
inet_pton(AF_INET,”192.168.7.89”, (void *)& mreq.imr_interface);

setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,  
                  sizeof(mreq));

六、UNIX域套接字

socket同样可以用于本地通信

创建套接字时使用本地协议PF_UNIX(或PF_LOCAL)。
  socket(AF_LOCAL, SOCK_STREAM, 0)
  socket(AF_LOCAL, SOCK_DGRAM, 0)

分为流式套接字和用户数据报套接字

和其他进程间通信方式相比使用方便、效率更高

常用于前后台进程通信
本地地址结构
       struct sockaddr_un        //  <sys/un.h>
        {
             sa_family_t  sun_family;
             char  sun_path[108];         // 套接字文件的路径
         };

填充地址结构
    struct sockaddr_un myaddr;
     bzero(&myaddr,  sizeof(myaddr));
     myaddr.sun_family = AF_UNIX;      strcpy(myaddr.sun_path,  “/tmp/mysocket”);

服务器端


                           socket(AF_UNIX, SOCK_STREAM, 0)

                           bind(,本地地址, )

                                 listen()

                                 accept(,,)

                                 recv() / send()

                                 ……

客户端

socket(PF_UNIX, SOCK_STREAM, 0)

               bind(,本地地址, )   //   可选

                     connect(,,)

                     recv() / send()

                     ……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qt历险记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值