1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > UDP socket编程: C++发送 | C#接收

UDP socket编程: C++发送 | C#接收

时间:2020-01-28 04:48:56

相关推荐

UDP socket编程: C++发送 | C#接收

文章目录

C++ 端发送在头文件中封装数据C文件错误处理C# 端接收简易显示接收代码C#端发送跨平台的C++端UDP

经常用UDP发送结构体数据,这里还是记录一下。

C++ 端发送

在头文件中封装数据

#pragma oncestruct Coor {int x;int y;};struct Ball{int id;Coor center;Coor up;Coor bottom;Coor left;Coor right;};const int MAX_NUMS = 10;struct DataFrame{int num;Ball balls[MAX_NUMS];};extern void UDP_init();extern void UDP_send(DataFrame& data);extern void UDP_close();

C文件

#include "udp.h"#include <iostream>#include <Winsock2.h>#define _WINSOCK_DEPRECATED_NO_WARNINGS#pragma comment(lib,"ws2_32.lib") using namespace std;static SOCKET sender;static sockaddr_in receiver;static char* sendData = nullptr;const int UDP_FRAME_LENGTH = sizeof(DataFrame);char ip[] = "127.0.0.1";int port = 9000;void UDP_init() {try {// 初始化Socketif (WSAStartup(MAKEWORD(2, 2), &WSADATA()) != 0){cout << "Initiates windows socket failed!" << endl;exit(-1);}sender = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);receiver.sin_family = AF_INET;receiver.sin_port = htons(port);receiver.sin_addr.S_un.S_addr = inet_addr(ip);const int UDP_FRAME_LENGTH = sizeof(DataFrame);}catch (...) {}}void UDP_send(DataFrame& data) {try {sendData = (char*)&data;sendto(sender, sendData, UDP_FRAME_LENGTH, 0, (sockaddr*)&receiver, sizeof(receiver));}catch (...) {}}void UDP_close() {closesocket(sender);}

错误处理

error C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_D

修改VS配置,告诉它我就要旧函数:

修改方法:项目 -> 属性 -> C/C++ ->常规->SDL检查,将“是”改为“否”,即可。文件的属性页 -> “预处理器” -> 将“_CRT_SECURE_NO_WARNINGS”加上

C# 端接收

简易显示

接收代码

其中关键点:结构体定义bytes数组转结构体

using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using .Sockets;using ;using System.Threading;using System.Runtime.InteropServices;namespace UDP{public partial class Form1 : Form{public Form1(){InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false; // 关闭跨线程检查UDP_start();tbox_display.AppendText("UDP Start!\r\n");}/// <summary>/// UDP 启动,绑定端口9000/// </summary>void UDP_start(){Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);IPAddress ip = IPAddress.Parse("127.0.0.1");IPEndPoint port = new IPEndPoint(ip, 9000);socket.Bind(port);Thread th = new Thread(receive);th.IsBackground = true;th.Start(socket);}public struct Coor{public int x;public int y;}public struct Ball{public int id;public Coor center;public Coor up;public Coor bottom;public Coor left;public Coor right;}public struct Data{public int num;[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_NUMS)]public Ball[] balls;};const int MAX_NUMS = 10;public Data data;void receive(object o){Socket socket = o as Socket;while (true){EndPoint remote_port = new IPEndPoint(IPAddress.Any, 0);byte[] buffer = new byte[Marshal.SizeOf(data)];int len = socket.ReceiveFrom(buffer, ref remote_port);if (len != buffer.Length) // 滤过错误格式的数据帧{string msg = Encoding.UTF8.GetString(buffer, 0, len);tbox_display.AppendText(remote_port.ToString() + ":" + msg + "\r\n");continue;}data = (Data)ByteToStruct(buffer, typeof(Data));display(); }}public static object ByteToStruct(byte[] bytes, Type type){int size = Marshal.SizeOf(new Data());IntPtr structPtr = Marshal.AllocHGlobal(size);Marshal.Copy(bytes, 0, structPtr, size);object obj = Marshal.PtrToStructure(structPtr, type);Marshal.FreeHGlobal(structPtr);return obj;}void display(){for (int i = 0; i < data.num; i++){Ball b = data.balls[i];tbox_display.AppendText(b.id.ToString() + ":"+ String.Format("({0},{1})", b.center.x, b.center.y) + ","+ String.Format("({0},{1})", b.up.x, b.up.y) + ","+ String.Format("({0},{1})", b.bottom.x, b.bottom.y) + ","+ String.Format("({0},{1})", b.left.x, b.left.y) + ","+ String.Format("({0},{1})", b.right.x, b.right.y) + "\r\n");}}}}

C#端发送

如果用C#端进行数据发送,则需要将结构体数据转换为byte数组,代码如下:

int size = Marshal.SizeOf(data);byte[] bytes = new byte[size];IntPtr structPtr = Marshal.AllocHGlobal(size);Marshal.StructureToPtr(data, structPtr, false);Marshal.Copy(structPtr, bytes, 0, size);Marshal.FreeHGlobal(structPtr);

其中的结构体定义和上面一致,然后进行发送即可。具体UDP发送代码可以参考 上一篇:

socket.SendTo(bytes, remote_port);

跨平台的C++端UDP

头文件

#pragma once#include <vector>const int MAX_LEN=10;namespace udp {struct DataFrame {int num;int labels[MAX_LEN];};const int UDP_FRAME_LENGTH = sizeof(udp::DataFrame);void open();void send(DataFrame &data);void receive();void stop();}

C文件

#include "udp.h"#include <string>#ifdef __linux__#include <sys/socket.h>#include <unistd.h>#include <arpa/inet.h>#define SOCKET int#else#include <winsock2.h>#endifusing namespace std;static SOCKET sender; // localstatic sockaddr_in receiver; // remotestatic char *sendData = nullptr;int remote_port = 9000;static string remote_ip = "127.0.0.1"; //NOLINTvoid udp::open() {try {#ifdef __WIN32if (WSAStartup(MAKEWORD(2, 2), &WSADATA()) != 0){cout << "Initiates windows socket failed!" << endl;exit(-1);}#elif __linux__#endifsender = socket(AF_INET, SOCK_DGRAM, 0);receiver.sin_family = AF_INET;receiver.sin_port = htons(remote_port);receiver.sin_addr.s_addr = inet_addr(remote_ip.c_str());}catch (...) {}}void udp::send(DataFrame &data) {try {sendData = (char *) &data;sendto(sender, sendData, UDP_FRAME_LENGTH, 0, (sockaddr *) &receiver, sizeof(receiver));}catch (...) {}}void udp::receive() {}void udp::stop() {#ifdef __WIN32closesoceket(sender);WSACleanup();#elif __linux__close(sender);#endif}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。