C++ UDP通信

#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>
#endif

class 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>
#endif

XUdp::XUdp(unsigned short port)
{
	//初始化动态链接库
	//引用lib库
#ifdef WIN32  //linux下不用初始化网络库
	static bool first = true;
	if (first)
	{
		first = false;						 //只在首次进入时初始化网络库
		WSADATA ws;					         //加载Socket库   项目属性-链接器-输入加上 ws2_32.lib
		WSAStartup(MAKEWORD(2, 2), &ws);     //动态库引用加1    
	}
#endif
	uport = 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 WIN32
	int 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;
#else
	struct 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 WIN32
	int 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);
#else
	struct 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;
}

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值