网络编程(1)——TCP、UDP

1.基础知识

1.概念

不同主机的进程间通信

2.基本通信流程

ip地址 ---就是网络中身份证 ---- 用来唯一的标识一台主机

 ip = 网络号 + 主机号 

ip 本质 32位的数值 

点分十进制 

子网掩码

255.255.255.0

用来区分网络

默认网关

用于发送ip

DNS

将域名转化为用于寻址的ip地址

3.分层

osi模型 (开放的系统互联模型) 
        7.应用层 //  
        6.表示层 //加密传输的需要  --- 数据的格式化 
                  加密解密  gzip


        5.会话层 //连接状态 --长连接 ,短链接,连接的质量问题 
                 网络断开,连接状态,keep-close keep-alive
                 //登录某个网站:
               
        4.传输层 //传输控制协议 
                 tcp  udp  协议  文件    视频,音频
                 可靠传输 & 
               tcp: 
                   下载文件,传输文件。
               udp:
                   音频,视频,游戏开黑
                              
        3.网络层         ----- 数据包 (packet)
                ip   NAT   
               //怎么找到 对方

        2.链路层   (封装成帧 + 差错控制)      
              交换机   (全双工,实时的工作的。)
              数据的格式化  (大量数据交互时,字节为单位,字节大小端)
              帧      
              校验
                       
        1.物理层      ----- bit流    
            100Mb/8  Gbits   100MB 同轴电缆
            (
              电气特性: 0,1高低电平特性
              物理特性: 0,1

              规程特性: 超5类 ,超6类,远距离传输

2.tcp编程函数接口

1.socket 

#include <sys/types.h>          /* See NOTES */
    #include <sys/socket.h>
    int socket(int domain, int type, int protocol);
    功能:
        创建了通信的一端 
        返回文件描述符 
    参数:
    @domain    //域 -- 范围 
               //ip地址 
               // ipv4  32位数据 
               // ipv6  128位 
               //本地套接字 
               //protocol //协议
               AF_INET
   @type       //用来说明socket这种网络通信的文件的类型 
            SOCK_STREAM   //流式套接字 ---tcp 
            SOCK_DGRAM     //数据报套接字 ---udp
  @protocol   //协议 
             0    //linux系统上 SOCK_STREAM --- TCP
                  //类linux系统行 
                  //          SOCK_DGRAM --- UDP
   返回值:
   成功  返回socket对应的fd
   失败  -1 && errno被设置  //perror 

注:两个重点协议

TCP(transmision control protocol):(类似 打电话)---可靠(1.连接 2.可靠传输 3.字节流)
1.特点:
    a.面向连接(就是在进行通信之前,必须建立好一条逻辑上的通路)
    b.提供可靠传输(四个"无",无丢失,无失序,无差错,无重复)

2.建立连接: 
        tcp三次握手 目的:建立连接

        client      ------------------  server
        1           -- 我要通话     -->  1   //连接的请求 
        2           <--嗯,我知道了,你可以-- //对方接听电话 喂 
        3            -- 嗯,好的     -->     //喂

3.应用场合:
    (1). 对可靠性要求较高场合
    (2). QQ微信等 软件的登录
 

UDP(User datagram Protocol):(类似 生活中的广播) (1.不可靠, 2.无连接 3.数据报)
1.特点:
         不提供可靠传输,
         在数据发送时,不需要建立连接

2.应用:
    (1).小数据,但是对速度要求较高
    (QQ.及时文本信息,语音等),实时性要求较高场合!
    (2).广播,组播   //电子教师(vnc --- 广播)
    (3).无线网的传输 //udp 

2.connect

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
 功能:
    通过socket链接到指定的地址上 
 参数:
    @sockfd  --- socket创建的fd
    @addr    --- 标识网络中一个进程对应的地址 
                 ip      确定一台主机 
                 端口号   用来标识一个网络通信的进程 
                 ip+端口号 
   struct sockaddr *addr//不是通用的 
   socket 不同的通信范围 
   不同通信域 都有自己特定的结构体 
   ipv4
        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 -- ip地址*/
        };                                                                                                                                                          /* Internet address. */
        struct in_addr {
        in_addr_t      s_addr;     /* address in network byte order */
        };
        in_addr_t inet_addr(const char *cp);
  @addrlen  
        说明 第二个参数的 地址类型的大小 
返回值:
   成功 0
   失败 -1&&errno                                                                                                                       

端口号:
  16位的整型数据 

  0~1023 //1024 ---知名端口号 
               //http -- 80 
  1024~50000  //特定端口号 
  50000~  //临时分配的端口号 
  
  大小端 
  发送 --- 转换 --- 网络字节序 (大端)
  接收 --- 根据主机的大小端转换 
#include <arpa/inet.h>

uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);

h -- host
to -- 到 
n --network 

l -- long   //处理4字节数据 
s -- short  //处理2字节数据 


in_addr_t inet_addr(const char *cp);
cp 表示要用的ip地址的字符串 //点分十进制 
"192.168.0.150"
返回:
   网络字节序形式的ip地址的32位数值 

    

3.bind

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
int bind   (int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:
   给sockfd 绑定一个地址信息(ip+port)
参数:
  @sockfd  --- 要操作的socket 
  @addr    --- 要绑定的地址信息 
  @addrlen --- 地址信息对应的大小 
返回值:
     成功 0
   失败 -1&&errno

4.listen

 int listen(int sockfd, int backlog);
  功能:
     将sockfd对应的socket设置为监听套接字 
     //这个套接字 负责看 有没有客户端,发送连接请求 
     //有了放等待队列中
  参数:
  @sockfd  ---socket 的fd
  @backlog  --- 等待队列的长度 
返回值:
   成功 0
   失败 -1&&errno
   //dos 攻击 

5.accept 

int accept (int sockfd,     struct sockaddr *addr, socklen_t *addrlen);
功能:
   从监听的socket中提取连接请求,完成连接(三次握手)
   返回已连接的一个新socket 
参数:
  @sockfd --- 监听的socket的fd
  @addr   --- 用来存放,客户端的地址信息 
  @addrlen --- 值结果参数 
               注意:  必须初始化 ,初始成 addr对应sockaddr_in 类型的大小               
返回值:
  成功 返回 已连接的socket的fd  //专门用于后面通信的 
  失败 -1 &&errno 

6.send

 ssize_t read(    int fd, void *buf, size_t count );

      recv(sockfd,buf,sizeof(buf),0);<=>read(sockfd,buf,sizeof(buf),0);
      
      ssize_t send(int sockfd, const void *buf, size_t len  , int flags);
      功能:
          向socket中发送信息 
      参数:
        @sockfd --- 要操作的socket
        @buf    --- 存放数据的空间 
        @len    --- 发送的数据大小 
        @flags  --- 操作标志
                   MSG_DONTWAIT
      返回值:
         成功 发送出去字节数 
         失败 -1 && errno 

7.recv

  ssize_t recv(int sockfd, void *buf, size_t len  , int flags);
      功能:
          从socket中接收信息 
      参数:
        @sockfd --- 要操作的socket
        @buf    --- 存放数据的空间 
        @len    --- buf的大小 
        @flags  --- 指定读取信息的操作标志
                   MSG_DONTWAIT
      返回值:
         成功 读取到的字节数 
         失败 -1 && errno 

 3.udp编程函数接口

1.socket
2.sendto

ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);

 功能:
          向socket中发送信息 
      参数:
        @sockfd --- 要操作的socket
        @buf    --- 存放数据的空间 
        @len    --- 发送的数据大小 
        @flags  --- 操作标志
                   MSG_DONTWAIT
        @dest_addr  --- 要发送到的目的地址 
        @addrlen    --- 地址大小
      返回值:
         成功 发送出去字节数 
         失败 -1 && errno 

3.bind
4.recvfrom

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
      功能:
          从socket中接收信息 
      参数:
        @sockfd --- 要操作的socket
        @buf    --- 存放数据的空间 
        @len    --- buf的大小 
        @flags  --- 指定读取信息的操作标志
                   MSG_DONTWAIT
        @src_addr --- 保存 客户端的地址信息 
        @addrlen  --- 值结果参数 
                      注意: 
                         使用时,需要 初始化 addrlen = sizeof(struct sockaddr_in);
      返回值:
         成功 读取到的字节数 
         失败 -1 && errno 

4.交互过程

1.tcp

客户端 

  • socket
  • connect
  • recv/send
  • close

服务器端

  • socket 
  • bind
  • listen
  • accept 
  • recv/send
  • close

:交互过程中可能会出现粘包现象,是因为tcp的交互的特殊性导致的

       解决方式:要让消息之间有边界 

        a. 结束标志 \r\n 
        b. 固定长度 
        c. 协议结构体 

    2.udp

    客户端:主动 

    • socket
    • sendto 
    • recvfrom 
    • close

    服务器端:被动 

    • socket
    • bind
    • recvfrom
    • printf
    • sendto
    • close 

    评论
    成就一亿技术人!
    拼手气红包6.0元
    还能输入1000个字符
     
    红包 添加红包
    表情包 插入表情
     条评论被折叠 查看
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值