udp基础

udp_server.h 

#pragma once
#include <iostream>
#include <cerrno>
#include <cstring>
#include <cstdlib>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
namespace ns_server
{
    enum{
        SOCKET_ERR=1,
        BIND_ERR
    };

    const static uint16_t default_port = 8080;

    class UdpServer
    {
    public:
        UdpServer(std::string ip, uint16_t port = default_port): ip_(ip), port_(port)
        {
            std::cout << "server addr: " << ip << " : " << port_ << std::endl;
        }
        void InitServer()
        {
            // 1. 创建socket接口,打开网络文件
            sock_ = socket(AF_INET, SOCK_DGRAM, 0);//int socket(int domain, int type, int protocol);domain是标识你是想要网络通信还是本地通信,type表示的是套接字的种类,创建成功返回文件描述符
            //AF_INET标识生成网络通信套接字,SOCK_DGRAM提供的是数据报通信,SOCK_STREAM提供的是数据流通信,第三个参数标识采用协议,默认为0,由系统根据第二个参数type进行判定。
            if(sock_ < 0)
            {
                std::cerr << "create socket error: " << strerror(errno) << std::endl;
                exit(SOCKET_ERR);//直接终止该进程
            }
            std::cout << "create socket success: " << sock_ << std::endl; //该文件符在当前情况下一般是3

            // 2. 给服务器指明IP地址和Port(填写sockaddr信息)
            struct sockaddr_in local;  // 这个 local 在哪里定义呢?用户空间的特定函数的栈帧上,不在内核中!我们需要通过bind将loacl设置内核当中
            bzero(&local, sizeof(local));//void bzero(void *s, size_t n);将local变量直接清零

            local.sin_family = AF_INET; //也可以写成PF_INET,标识网络间通信,也就是该结构体的前16个比特位
            local.sin_port = htons(port_);//port_是端口号,端口号这个两字节的数据必须出现在网络当中,方便目标进程将消息发回来,而htons是为了是将主机字节序转换成网络字节序,使网络程序具有可移植性,使同样的c代码在大端和小段计算机编译后。
            // inet_addr: 1,2
            // 1. 字符串风格的IP地址,转换成为4字节int, "1.1.1.1" -> uint32_t -> 能不能强制类型转换呢?不能,这里要转化,强转并不改变数据二进制的构成,只是将数据类型做转换。
            // 2. 需要将主机序列转化成为网络序列
            local.sin_addr.s_addr = inet_addr(ip_.c_str());//in_addr_t inet_addr(const char *cp)是将一个点分十进制风格的字符串地址转换成int类型地址,同时也将主机序列转换成为了网络序列 
            if(bind(sock_, (struct sockaddr*)&local, sizeof(local)) < 0)//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen),第一个参数是套接字,第二个是一个通用的结构体类型,第三个参数第二个参数的实际长度;bind是把已经填充好的local套接字字段和文件字段进行绑定关联,从而称为网阔文件  
            {
                std::cerr << "bind socket error: " << strerror(errno) << std::endl;
                exit(BIND_ERR);
            }
            std::cout << "bind socket success: " << sock_ << std::endl; 
        }
        void Start()
        {
        } 
        ~UdpServer() {}

    private:
        int sock_;//关于套接字的文件描述符
        uint16_t port_;
        std::string ip_; // 此ip地址是字符串风格的,比如:"1.1.1.1"。后面要专门研究一下,后面要去掉这个ip
    };
} // end NS_SERVER 

udp_server.c  

#include "udp_server.hpp"
#include <memory>
using namespace ns_server;
using namespace std;
int main()
{
    unique_ptr<UdpServer> usvr(new UdpServer("1.1.1.1", 8082));

    usvr->InitServer(); //服务器的初始化
    usvr->Start();//启动服务器

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值