IPV4流媒体广播系统04

接上一篇: IPV4流媒体广播系统03

1. 网络套接字

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.

1.取得SOCKET
2.给SOCKET取得地址(可省略)
3.收/发消息
4.关闭SOCKET

开发思路:

(1) man socket
  socket()函数的作用:socket()  creates an endpoint for communication and return
s a descrip-tor.

 int socket(int domain, int type, int protocol);
   第一个参数是协议族,这里选AF_INET 表示ipv4
   第二个参数是 传输数据的类型,这里选 SOCK_DGRAM 传输报文
   第三个参数 直接写0 不用管他
返回值: 返回一个文件描述符,man socket 中的原话是这样
RETURN VALUE
       On success, a file descriptor for the  new  socket  is  returned.   On
       error, -1 is returned, and errno is set appropriately.
(2) man 2 bind
NAME
       bind - bind a name to a socke
       
int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);
第二个参数的描述是:
第二个参数实际上不存在,是捏造的,他取决于你用的 address family协议 , 你用哪个协议族,就把你的协议族的地址填在那儿
 The  actual  structure passed for the addr argument will depend on the
  address family.  The sockaddr structure is defined as something like:

           struct sockaddr {
               sa_family_t sa_family;
               char        sa_data[14];
           }

       The only purpose of this structure is to cast  the  structure  pointer
       passed  in  addr  in  order  to  avoid compiler warnings.  See EXAMPLE
       below.          
你用的是哪个协议就去哪个协议找对应的 address families
The rules used in name binding vary between address families.  Consult
 the manual entries in Section 7 for detailed information.  For AF_INET
 see  ip(7),  for  AF_INET6  see  ipv6(7), for AF_UNIX see unix(7), for
 AF_APPLETALK see ddp(7), for AF_PACKET see packet(7), for  AF_X25  see
 x25(7) and for AF_NETLINK see netlink(7).
 我们这里用的协议是 AF_PACKE 我们去看一下 第7章  使用命令 man 7 ip

Address format
       An IP socket address is defined as a combination of  an  IP  interface
       address and a 16-bit port number.  The basic IP protocol does not sup‐
       ply port numbers, they are implemented by higher level protocols  like
       udp(7) and tcp(7).  On raw sockets sin_port is set to the IP protocol.
			 //我们用用到的就是  ipv4  ,使用 sockaddr_in 这个结构体
           struct sockaddr_in {
               sa_family_t    sin_family; /* address family: AF_INET */
               in_port_t      sin_port;   /* port in network byte order */
               struct in_addr sin_addr;   /* internet address */
           };

           /* Internet address. */
           struct in_addr {
               uint32_t       s_addr;     /* address in network byte order */
           };

在这里插入图片描述
第5个参数对端地址是,回填的数据
传输的报文
proto.h

#ifndef PROTO_H__
#define PROTO_H__ 

#define PROTO_H__ 

#define RCVPORT "1989"
#define NAMESIZE 11 
struct msg_st 
{
        uint8_t name[NAMESIZE];
        uint32_t math;
        uint32_t chinese;
}__attribute__((packed)); 
    

#endif 

服务端接收报文:

#include <stdio.h>
  2 #include <stdlib.h>
  3 #include <sys/types.h>          /* See NOTES */
  4 #include <sys/socket.h>
  5 #include <arpa/inet.h>
  6 #include "proto.h"
  7 #define IPSTRSIZE 40
  8 int main()
  9 {
 10         int sd;
 11         struct sockaddr_in laddr,raddr;
 12         char ipstr[IPSTRSIZE];
 13         sd = socket(AF_INET,SOCK_DGRAM,0);//第一个参数是ipv4,第二个是数据格
    式是//报文
 14         struct msg_st rbuf;//我知道你要给我发结构体来,我要定义一个接收
 15         socklen_t raddr_len;
 16         if(sd<0)
 17         {
 18                 perror("socket()");
 19                 exit(1);
 20         }
         laddr.sin_family = AF_INET;
 22         laddr.sin_port = htons(atoi(RCVPORT));
 23 
 24         //inet_pton可以把ip地址点分式转换成大整数
 25 //@parm1: 协议族ipv4或ipv6 @parm2:source 也就你自己的ip,0.0.0.0 万能地址,本26 //@parm3: 转换完放到的位置
 27         inet_pton(AF_INET,"0.0.0.0",&laddr.sin_addr);
 28         if(bind(sd,(void *)&laddr,sizeof(laddr))<0)
 29         {
 30                 perror("bind()");
 31                 exit(1);
 32         }
 33         raddr_len = sizeof(raddr);//必须初始化
 34         while(1)
 35         {
 36         recvfrom(sd,&rbuf,sizeof(rbuf),0,(void *)&raddr,&raddr_len);
 37 //第5个参数 是回填的.
 // inet_notp 把一个大整数转化成点分式
 39  inet_ntop(AF_INET,&raddr.sin_addr,ipstr,IPSTRSIZE);//@parms1 协议族 @parms
    2//转换的参数
 40 //@parms3 放到那块空间去 @parm4 那块空间有多大
 41 printf("----Message from %s:%d--\n",ipstr,ntohs(raddr.sin_port));
 42 printf("NAME = %s\n",rbuf.name);
 43 printf("MATH = %d\n",ntohl(rbuf.math));
 44 printf("CHINESE = %d\n",ntohl(rbuf.chinese));
 45 
 46 }
 47         close(sd);
 48         exit(0);
 49 
 50 }

netstat -anu
在这里插入图片描述

客户端代码:

#include <stdio.h>
  2 #include <stdlib.h>
  3 #include <sys/types.h>          /* See NOTES */
  4 #include <sys/socket.h>
  5 #include <arpa/inet.h>
  6 #include <string.h>
  7 #include "proto.h"
  8 #define IPSTRSIZE 40
  9 
 10 int main(int argc,char * argv[])
 11 {
 12         if(argc<2)
 13         {
 14                 fprintf(stderr,"Usage...\n");
 15                 exit(1);
 16         }
 17         int sd;
 18         struct sockaddr_in raddr;
 19         char ipstr[IPSTRSIZE];
 20         sd = socket(AF_INET,SOCK_DGRAM,0);//第一个参数是ipv4,第二个是数据格
    //式是报文
          struct msg_st sbuf;//我知道你要给我发结构体来,我要定义一个接收
 22         socklen_t raddr_len;
 23         if(sd<0)
 24         {
 25                 perror("socket()");
 26                 exit(1);
 27         }
 28 
 29         //构造数据
 30         strcpy(sbuf.name,"xiaoming");
 31         sbuf.math = htonl(rand()%100);
 32         sbuf.chinese = htonl(rand()%100);
 33         raddr.sin_family = AF_INET;
 34         raddr.sin_port = htons(atoi(RCVPORT));
 35         inet_pton(AF_INET,argv[1],&raddr.sin_addr);
  if(sendto(sd,&sbuf,sizeof(sbuf),0,(void *)&raddr,sizeof(raddr))<0)
 39         {
 40                 perror("sendto()");
 41                 exit(1);
 42         }
 43         puts("OK!");
 44         close(sd);
 45         exit(0);
 46 
 47 }
                       

整体效果:

在这里插入图片描述

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页