网络编程复习2udp通信实现代码

 udpsocket.hpp

/*
 * 封装udpsocket类,通过实例化的对象,
 * 调用自己的类成员接口可以在外部更加简单地完成客户端与服务端的搭建
 */
#include<cstdio>
#include<iostream>
#include<string>
#include<unistd.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<sys/socket.h>

class UdpSocket
{ 
  private:
  int _sockfd;

  public:
    UdpSocket():_sockfd(-1){}
    bool Socket()
    { 
      _sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
      if(_sockfd<0)
      {
        perror("socket error\n");
        return false;
       }
      return true;
    }
    bool Bind(const std::string &ip, uint16_t port)
    {
      struct sockaddr_in addr;
      addr.sin_family = AF_FILE;
      addr.sin_port = htons(port);
      addr.sin_addr.s_addr = inet_addr(ip.c_str());
      socklen_t len = sizeof(struct sockaddr_in);
      int ret = bind(_sockfd,(struct sockaddr*)&addr,len);
      if(ret<0)
      {
        perror("bind error\n");
        return false;
      }
      return true;
    }
    bool Send(const std::string &data,const std::string &ip, uint16_t port )
    {
      struct sockaddr_in addr;
      addr.sin_family = AF_INET;
      addr.sin_port = htons(port);
      addr.sin_addr.s_addr = inet_addr(ip.c_str());
      socklen_t len = sizeof(struct sockaddr_in);
      int ret = sendto(_sockfd, data.c_str(),data.size(),0,(struct sockaddr*)&addr,len);
      if(ret<0)
      {
        perror("sendto error");
        return false;
      }
      printf("发送成功\n");
      return true;
    }
    bool Recv(std::string *buf, std::string *ip=NULL, uint16_t *port=NULL)
    {
       struct sockaddr_in addr;
       socklen_t len = sizeof(struct sockaddr_in);
       char tmp[4096] = {0};
       int ret = recvfrom(_sockfd,tmp,4096,0,(struct sockaddr*)&addr,&len);
      //int ret= recvfrom(_sockfd,tmp,4096,0,(struct sockaddr*)&addr,&len);

       if(ret<0)
       {
        perror("recv error\n");
        return false;
       }

       buf->assign(tmp,ret);//申请空间并拷贝数据到buf

       if(ip != NULL)
       {
         *ip= inet_ntoa(addr.sin_addr);
       }

       if(port != NULL)
       {
        *port = ntohs(addr.sin_port);
       }
       return true;
    }
    bool Close()
    {
      if(_sockfd != -1)
      {
        close(_sockfd);
      }
      return true;
    }
};

 udp_srv.c

#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>//字节序转换接口头文件
#include<netinet/in.h>//地址结构协议类型头文件
#include<sys/socket.h>//socket接口头文件

int main()
{
  //1. 创建套接字
  //int sockei(地址域类型,套接字类型,协议类型)
  int sockfd = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
  if(sockfd<0)
  {
    perror("socket error");
    return -1;
  }

  //2.绑定地址信息
  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(9000);//将主机字节序转换成网络字节序
  addr.sin_addr.s_addr = inet_addr("10.0.4.7");
  socklen_t len = sizeof(struct sockaddr_in);

  // int bind(描述符,地质结构,地址长度)
  int ret = bind(sockfd,(struct sockaddr*)&addr,len);
  if(ret<0)
  {
    perror("bind error");
    return -1;
  }

  while(1)
  {
    //3.接收数据
    //recvfrom(描述符,空间,长度,标志位,对端地址,长度)
    char buf[1024] = {0};
    struct sockaddr_in peer_addr;
    ret = recvfrom(sockfd,buf,1023,0,(struct sockaddr*) &peer_addr,&len);
    if(ret<0)
    {
      perror("recvfrom error\n");
      close(sockfd);
      return -1;
    }
    printf("client-[%s:%d] say:%s\n", 
        inet_ntoa(peer_addr.sin_addr),
        ntohs (peer_addr.sin_port),
        buf);
    //4.发送数据
    memset(buf,0x00,1024);
    printf("Sever say:");
    fflush(stdout);
    fgets(buf,1023,stdin);
    ret =  sendto(sockfd, buf, strlen(buf),0,(struct sockaddr*) &peer_addr,len);
    if(ret<0)
    {
      perror("sendto error\n");
      close(sockfd);
      return -1;
    }
  }
  //5.关闭套接字
  close(sockfd);

  return 0;
}

udp_cli.cpp

#include "udp_socket.hpp"

#define  CHECK_RET(q) if((q)==false){return -1;}
int main()
{
  //1.创建套接字
  UdpSocket sock;
  CHECK_RET(sock.Socket());
  //2.绑定地址信息(不推荐)
  while(1)
  {
  //3.发送数据
    std::string buf;
    std::cout<<"client say: ";
    std::cin>>buf;
  CHECK_RET(sock.Send(buf,"10.0.4.7",9000));
  //4.接收数据
  buf.clear();
  CHECK_RET(sock.Recv(&buf));
  std::cout<<"server say: "<<buf<<std::endl;
  }
  //5.关闭套接字
  CHECK_RET(sock.Close());
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值