#pragma once
#ifndef XUDP_H
#define XUDP_H#ifdef WIN32
#include <windows.h>
#define socklen_t int
#else
#include <arpa/inet.h>
#define closesocket close //替换close函数
#include <unistd.h>#include<iostream>
#endifclass XUdp
{
public:int CreateSocket(); // 1 创建套接字bool Bind(); // 2 绑定并监听端口号int Send(const char* buf, int size, char* ip, unsigned short port); //3 发送数据int Recv(char* buf, int bufsize, sockaddr_in* from); // 4 接收数据void Close(); // 5 关闭连接int SetRecvTimeout(int sec); //设置udp接收超时int SetSendTimeout(int sec); //设置udp发送超时XUdp(unsigned short port = 9000);virtual ~XUdp();private:int usock = 0; //udp服务端的socket create成员函数自己生成unsigned short uport = 0; //构造函数从外获取};
#endif
#include "XUdp.h"
#include <iostream> //IO流操作
#include <string> //string标准库
#ifdef WIN32
#include <windows.h>
#define socklen_t int#else
#include <arpa/inet.h>
#define closesocket close //替换close函数
#include <unistd.h>
#include <pthread.h>
#endifXUdp::XUdp(unsigned short port)
{//初始化动态链接库//引用lib库
#ifdef WIN32 //linux下不用初始化网络库static bool first = true;if (first){first = false; //只在首次进入时初始化网络库WSADATA ws; //加载Socket库 项目属性-链接器-输入加上 ws2_32.libWSAStartup(MAKEWORD(2, 2), &ws); //动态库引用加1 }
#endifuport = port;printf("port:%d connect ! \n",port);
}XUdp::~XUdp()
{//delete this;
}int XUdp::CreateSocket() //创建套接字
{usock = socket(AF_INET, SOCK_DGRAM, 0); //TCP/IP UDP 创建udp 套接字if (usock == -1){printf("create udp socket failed.\n");return -1;}printf("create udp socket success.\n");return 0;
}void XUdp::Close() //关闭连接
{if (usock <= 0) return; //socket出错closesocket(usock); //已宏定义usock = 0;uport = 0;
}bool XUdp::Bind() //绑定并监听端口号
{sockaddr_in saddr; //数据结构saddr.sin_family = AF_INET; //协议saddr.sin_port = htons(uport); //端口,主机字节序(小端方式)转换成网络字节序(大端方式)// saddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); saddr.sin_addr.s_addr = htonl(INADDR_ANY); //绑定IP到广播地址INADDR_ANY 0.0.0.0 为了兼容linux if (bind(usock, (sockaddr*)&saddr, sizeof(saddr)) != 0) //安装sockaddr_in数据结构绑定套接字{printf("udp bind port %d failed.\n", uport);return false;}printf("udp bind port %d success.\n", uport);return true;
}int XUdp::Send(const char* buf, int size, char* ip, unsigned short port) //发送数据(强制全部发送)
{int sendedSize = 0; //已发送成功的长度sockaddr_in saddr;saddr.sin_family = AF_INET; //tcp/ip协议saddr.sin_port = htons(port);//服务端的端口 主机字节序转换成网络字节序saddr.sin_addr.s_addr = inet_addr(ip); //本机的ip地址 字符串ip地址转成整型while (sendedSize != size) //若没发送完成,则从断点开始继续发送 直到完成{int len = sendto(usock, buf + sendedSize, size - sendedSize, 0, (sockaddr*)&saddr, sizeof(saddr));if (len <= 0)break;sendedSize += len;}return sendedSize;
}int XUdp::Recv(char* buf, int bufsize, sockaddr_in* from) //接收数据
{socklen_t len = sizeof(sockaddr_in);int re = recvfrom(usock, buf, bufsize, 0, (sockaddr*)from, &len); //返回接收的客户端的网络地址,存在在地址中return re;
}int XUdp::SetRecvTimeout(int sec = 1) //设置udp接收超时
{
#ifdef WIN32int udp_rev_time = sec * 1000;if (setsockopt(usock, SOL_SOCKET, SO_RCVTIMEO, (char*)&udp_rev_time, sizeof(int)) < 0){printf("set udp receive failed.\n");return -1;}printf("set udp recv timeout success. %d seconds\n", sec);return 0;
#elsestruct timeval udp_rev_time;udp_rev_time.tv_sec = sec;udp_rev_time.tv_usec = 0;if (setsockopt(usock, SOL_SOCKET, SO_RCVTIMEO, (char*)&udp_rev_time, sizeof(udp_rev_time)) < 0){printf("set udp receive failed.\n");return -1;}printf("set udp recv timeout success. %d seconds\n", sec);return 0;
#endif
}int XUdp::SetSendTimeout(int sec = 1) //设置udp发送超时
{
#ifdef WIN32int udp_rev_time = sec;if (setsockopt(usock, SOL_SOCKET, SO_SNDTIMEO, (char*)&udp_rev_time, sizeof(int)) < 0){printf("set udp send failed.");return -1;}return 0;printf("set udp send timeout success. %d seconds\n", sec);
#elsestruct timeval udp_rev_time;udp_rev_time.tv_sec = sec;udp_rev_time.tv_usec = 0;if (setsockopt(usock, SOL_SOCKET, SO_SNDTIMEO, (char*)&udp_rev_time, sizeof(udp_rev_time)) < 0){printf("set udp send failed.");return -1;}printf("set udp send timeout success. %d seconds\n", sec);return 0;
#endif
}
接收:
#include"XUdp.h"
#include<stdio.h>int main()
{XUdp xudp(6000); // 绑定端口xudp.CreateSocket(); // int r = xudp.Bind();if (r == -1){printf("绑定失败:%d\n",GetLastError());xudp.Close();}char buff[256];int buffsize = sizeof(buff);SOCKADDR_IN client;while (1){int re = xudp.Recv(buff,buffsize, &client);if (re != -1){printf("recv_len = >%d \n", re);buff[re] = 0;printf("recv: %s \n",buff);}}system("pause");return 0;
}
发送创建
#include"client.h"
#include<stdio.h>
#include<iostream>int main()
{XUdp xudp(6000);xudp.CreateSocket();int r = xudp.Bind();if (r == -1){printf("绑定失败:%d\n", GetLastError());xudp.Close();}char buff[256];char ip[16];strcpy_s(ip,"127.0.0.1");while (1){memset(buff,0,256);printf("send:");scanf_s("%s",buff,sizeof(buff));xudp.Send(buff,strlen(buff),ip, 6000);}system("pause");return 0;
}