说明:两个客户端连接的是Kinect V2,需要将检测到的人体的数据信息发送到服务端进行系统数据的整体显示。指定的消息协议是ClientID|index|PosLeft|Left_S|PosRight|Right_S|ACTION| ClientID|index|PosLeft|Left_S|PosRight|Right_S|ACTION| ...
这是客户端根据检测到人体的数量向服务端发送的数据格式。
服务端:使用两个线程用于接收两个客户端的数据,将收到的数据添加到Queue中。在需要显示数据的Update中从Queue中取出数据进行处理控制。
这里服务端的接收数据脚本直接上代码:
using UnityEngine
using System.Collections
//引入库
using System.Net
using System.Net.Sockets
using System.Text
using System.Threading
using System.Collections.Generic
public class UdpHelpHandler : MonoBehaviour {
//以下默认都是私有的成员
Socket socket,socket2//目标socket
EndPoint clientEnd//客户端
IPEndPoint ipEnd,ipEnd2//侦听端口
string recvStr,recvStr2//接收的字符串
string sendStr//发送的字符串
byte[] recvData=new byte[1024]//接收的数据,必须为字节
byte[] recvData2=new byte[1024]//接收的数据,必须为字节
byte[] sendData=new byte[1024]//发送的数据,必须为字节
int recvLen,recvLen2//接收的数据长度
Thread connectThread,connectThread2//连接线程
int[] WaveCounts = new int[2]
int[] TPoseCounts = new int[2]
public Queue<string>queueClient1 = new Queue<string>()
public Queue<string>queueClient2 = new Queue<string>()
private System.Object thisLock = new System.Object ()
//初始化
public void InitSocket()
{
//定义侦听端口,侦听任何IP
ipEnd=new IPEndPoint(IPAddress.Any,2000)
//定义套接字类型,在主线程中定义
socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp)
//服务端需要绑定ip
try{
socket.Bind(ipEnd)
}
catch (System.Exception ex)
{
socket.Close ()
Debug.LogError(ex.Message + "\n" + ex.StackTrace)
}
//定义侦听端口,侦听任何IP
ipEnd2=new IPEndPoint(IPAddress.Any,3000)
//定义套接字类型,在主线程中定义
socket2=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp)
//服务端需要绑定ip
try{
socket2.Bind(ipEnd2)
}
catch (System.Exception ex)
{
socket2.Close ()
Debug.LogError(ex.Message + "\n" + ex.StackTrace)
}
//定义客户端
IPEndPoint sender=new IPEndPoint(IPAddress.Any,0)
clientEnd=(EndPoint)sender
print("waiting for UDP dgram")
//开启一个线程连接,必须的,否则主线程卡死
connectThread=new Thread(new ThreadStart(SocketReceive))
connectThread.Start()
//开启一个线程连接,必须的,否则主线程卡死
connectThread2=new Thread(new ThreadStart(SocketReceive2))
connectThread2.Start()
}
void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024]
//数据类型转换
sendData=Encoding.ASCII.GetBytes(sendStr)
//发送给指定客户端
socket.SendTo(sendData,sendData.Length,SocketFlags.None,clientEnd)
}
//服务器接收
void SocketReceive()
{
//进入接收循环
while(true)
{
//对data清零
recvData=new byte[1024]
//获取客户端,获取客户端数据,用引用给客户端赋值
recvLen=socket.ReceiveFrom(recvData,ref clientEnd)
//输出接收到的数据
recvStr=Encoding.ASCII.GetString(recvData,0,recvLen)
char[] msgDelim = { '|' }
string[] asMessages = recvStr.Split(msgDelim)
if (asMessages.Length >7) {
queueClient1.Enqueue (recvStr)
if (int.Parse (asMessages [0]) == 2) {
if (int.Parse (asMessages [6]) == 6) { //wave
SetWaveCountsClient1 (2)
}
} else if (int.Parse (asMessages [0]) == 3) {
if (int.Parse (asMessages [6]) == 6) { //wave
SetWaveCountsClient2 (3)
}
}
}
}
}
//服务器接收
void SocketReceive2()
{
//进入接收循环
while(true)
{
//对data清零
recvData2=new byte[1024]
//获取客户端,获取客户端数据,用引用给客户端赋值
recvLen2=socket2.ReceiveFrom(recvData2,ref clientEnd)
//输出接收到的数据
recvStr2=Encoding.ASCII.GetString(recvData2,0,recvLen2)
char[] msgDelim = { '|' }
string[] asMessages = recvStr2.Split(msgDelim)
if (asMessages.Length >7)
{
queueClient2.Enqueue (recvStr2)
if (int.Parse(asMessages[0]) == 2)
{
if(int.Parse(asMessages[6]) == 6) //wave
{
SetWaveCountsClient1(2)
}
}
else if (int.Parse(asMessages[0]) == 3)
{
if (int.Parse(asMessages[6]) == 6) //wave
{
SetWaveCountsClient2(3)
}
}
}
}
}
public void SetWaveCountsClient1(int index)
{
if (index == 2)
{
WaveCounts[0]++
}
}
public void SetWaveCountsClient2(int index)
{
if (index == 3)
WaveCounts[1]++
}
public void SetTposeCounts(int index)
{
if (index == 2)
TPoseCounts[0]++
else if (index == 3)
TPoseCounts[1]++
}
public int GetWaveCounts(int index)
{
int ret = 0
if (index == 2)
{
if (WaveCounts[0] >0)
ret = WaveCounts[0]--
}
else if (index == 3)
{
if (WaveCounts[1] >0)
ret = WaveCounts[1]--
}
return ret
}
public int GetTposeCounts(int index)
{
int ret = 0
if (index == 2)
{
if (TPoseCounts[0] >0)
ret = TPoseCounts[0]--
}
else if (index == 3)
{
if (TPoseCounts[1] >0)
ret = TPoseCounts[1]--
}
return ret
}
//返回接收到的字符串
public string GetRecvStr()
{
string returnStr=""
//加锁防止字符串被改
if (queueClient1.Count >0)
{
lock (/*thisLock*/queueClient1) {
//returnStr=recvStr
returnStr = queueClient1.Dequeue ()
}
}
return returnStr
}
//返回接收到的字符串
public void setRecvStr()
{
//加锁防止字符串被改
lock(thisLock)
{
recvStr = null
}
}
//返回接收到的字符串
public string GetRecvStr2()
{
string returnStr=""
if (queueClient2.Count >0)
{
lock (/*thisLock*/queueClient2) {
//returnStr=recvStr
returnStr = queueClient2.Dequeue ()
}
}
return returnStr
}
//返回接收到的字符串
public void setRecvStr2()
{
//加锁防止字符串被改
lock(thisLock)
{
recvStr2 = null
}
}
//连接关闭
public void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt()
connectThread.Abort()
}
if(connectThread2!=null)
{
connectThread2.Interrupt()
connectThread2.Abort()
}
//最后关闭socket
if(socket!=null)
socket.Close()
//最后关闭socket
if(socket2!=null)
socket2.Close()
print("disconnect")
}
}
客户端代码如下:
using UnityEngine
using System.Collections
//引入库
using System.Net
using System.Net.Sockets
using System.Text
using System.Threading
using System.Xml
//客户端
public class UdpHelpHandler : MonoBehaviour {
//以下默认都是私有的成员
Socket socket//目标socket
EndPoint serverEnd//服务端
IPEndPoint ipEnd//服务端端口
string recvStr//接收的字符串
string sendStr//发送的字符串
byte[] recvData=new byte[1024]//接收的数据,必须为字节
byte[] sendData=new byte[1024]//发送的数据,必须为字节
int recvLen//接收的数据长度
Thread connectThread//连接线程
public bool isClient =true
//初始化
public void InitSocket(string ipHostString,int port)
{
//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网
ipEnd=new IPEndPoint(IPAddress.Parse(ipHostString),port)
//定义套接字类型,在主线程中定义
socket=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp)
//定义服务端
IPEndPoint sender=new IPEndPoint(IPAddress.Any,0)
serverEnd=(EndPoint)sender
print("waiting for sending UDP dgram....")
//建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息
//开启一个线程连接,必须的,否则主线程卡死
connectThread=new Thread(new ThreadStart(SocketReceive))
connectThread.Start()
}
public void SocketSend(string sendStr)
{
//清空发送缓存
sendData=new byte[1024]
//数据类型转换
sendData=Encoding.ASCII.GetBytes(sendStr)
//发送给指定服务端
socket.SendTo(sendData,sendData.Length,SocketFlags.None,ipEnd)
}
//服务器接收
void SocketReceive()
{
//进入接收循环
while(true)
{
// print("recv thread")
//对data清零
recvData=new byte[1024]
//获取客户端,获取服务端端数据,用引用给服务端赋值,实际上服务端已经定义好并不需要赋值
recvLen=socket.ReceiveFrom(recvData,ref serverEnd)
// print("message from: "+serverEnd.ToString())//打印服务端信息
//输出接收到的数据
recvStr=Encoding.ASCII.GetString(recvData,0,recvLen)
// print(recvStr)
}
}
//连接关闭
public void SocketQuit()
{
//关闭线程
if(connectThread!=null)
{
connectThread.Interrupt()
connectThread.Abort()
}
//最后关闭socket
if(socket!=null)
socket.Close()
}
}
文章知识点与官方知识档案匹配
网络技能树首页概览
21577 人正在系统学习中
点击阅读全文
打开CSDN,阅读体验更佳
QT多线程,使用串口接收数据通过UDP端口进行数据转发_是小峰呀的博客-CS...
ui(newUi::Widget){ui->setupUi(this)socket=newQUdpSocket()localThread=newmyThread()timer=newQTimer()socket->bind(3080)//删除注释后,是由按钮控制数据发送,此时需要将带定时器的connet注释。
UDP数据通信,使用一个DatagramSocket实现向多个地址发送数据和接收各个...
往不同的服务器发送数据,只需要启动多个线程,调用上面的方法,替换地址和端口即可 //connect方法的意思是将socket与指定地址绑定,绑定成功后只能往该地址发送数据。并不是建立连接,因为udp是面向非连接的 mSocket.connect(address, hostPort...
c#向指定端口发送数据,监听指定端口
c#向指定端口发送数据,监听指定端口,使用端口监听获取数据信息,向指定端口发送需要的数据
最新发布 C# UDP发送和接收数据类
C# UDP发送和接收数据类
继续访问
UDP端口传递接收数据_wei395107171的博客
UDP端口传递接收数据 package com.udp.testimport java.io.BufferedReaderimport java.io.IOExceptionimport java.io.InputStreamReaderimport java.net.DatagramPacketimport java.net.DatagramSocket...
...解决端口复用的问题)_酷侠一剑绝ggh的博客_udp端口复用
UDP组播通信(解决端口复用的问题) 最近在写一个组播通信的功能,结果发现接受同一台电脑上只能运行一个接收端,如果运行两个时,第二个运行的程序不能收到数据。查找原因是因为没有设置端口数据复用的功能(setsockpot),setsockpot的调用...
NIO之UDP监听多个端口获取请求信息
最近需要继承一个udp服务,需求是这样的,服务端接收消息,并且支持多个udp端口。 例如: 客户端:port 11112 port 11113 port 11114 服务端:要可以同时监听这三个端口,接收发送的报文。 Select监听端口,然后获取请求数据 附代码 @Override public void run(String... args) throws Exception {...
继续访问
UDP客户端实现在不同端口上发送和接收数据
普通udp通信,客户端在发送完数据后,只需要在相同socket上,recvfrom即可 服务端给的回应,可以是同一端口,也可以是不同端口,客户端在接收时,需要指点一个本地端口进行接收,此端口也可以用bind和创建的socket绑定。 但是bind必须是在通过这个socket发送数据前绑定,在发送数据后再bind会失败。 下面给出代码: #define SEND_PORT 8000
继续访问
发送方 获取 绑定 端口 linux c,多播报文的发送和接收
1实验目的掌握多播的原理及如何进行多播报文的发送和接受2注意事项需包括ws2tcpip.h文件发送者和所有接受者在同一网内不考虑TTL值,回环状态通过setsockopt( )函数设置选项来实现多播数据的发送和接收3试验流程3.1多播数据发送端流程l创建一个数据报套接口l设置多播地址(例:239.192.1.2)和端口号(例:12345)l调用setsockopt( )函数设置发送的数据报本地接口...
继续访问
网络编程之 Udp接收数据
udp接收数据,网络调试助手担任发送方,但发送时需要对方的也就是虚拟机的ip 和端口,ip可以通过config获取,那么如何让一个程序拥有一个固定端口呢? 创建套接字的时候是没有端口号的,好比买了手机没有手机号,别...
继续访问
C语言实现UDP服务器,客户端
服务器 #include<stdio.h>#include "unistd.h" #include "sys/socket.h" #include "netinet/in.h" #include "arpa/inet.h" #include "string.h" #include "stdlib.h" #define IP "127.0.0.1" #define PORT 8888 int main() { int fb=0,len=0char buf[512]=
继续访问
c udp服务器端一对多持续接收消息,C - 使用select在多个端口上侦听的简单ipv6 udp服务器。从一个端口接收消息,而不是另一个...
#include #include #include #include #include int max(int socket_handle[])int main(void){int max_clients_allowed = 2int socket_handle[max_clients_allowed]int client_handle[max_clients_allowed]st...
继续访问
C# 简单的UDP服务器,实现异步接收UDP消息
C# 异步接收UDP消息 源代码 主要方法 async Task ListenForUdp(int port, Action<UdpReceiveResult>receivedHandle) { using (var udpClient = new UdpClient(port)) { while (true) { try { receivedHandle(await
继续访问
UDP数据通信,使用一个DatagramSocket实现向多个地址发送数据和接收各个地址的数据返回
有时候需要一个客户端向多个地址发送数据并接收返回的需求 1、创建DatagramSocket DatagramSocket 有多个构造方法 DatagramSocket():创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、本机所有可用端口中随机选择的某个端口。 DatagramSocket(int prot):创建一个DatagramSocket实例,并将该对象绑定到本机默认IP地址、指定端口。 DatagramSocket(int port, InetAddre.
继续访问
Python知识点——TCP和UDP的区别
相同点 UDP协议和TCP协议都是传输层协议。 TCP(Transmission Control Protocol,传输控制协议)提供的是面向连接,可靠的字节流服务。即客户和服务器交换数据前,必须现在双方之间建立一个TCP连接,之后才能传输数据。并且提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 UDP(User Data Protocol,用户数据报协议)是一个简单的面向数据报的运输层协议。它不提供可靠性,只是把应用程序传给IP层的数据报发送出去,但是不能保证它们能到达
继续访问
UDP多线程同时建立多个通信端口
1.需要注意的是:::bind(serSocket, (sockaddr*)&serAddr, sizeof(serAddr)) == SOCKET_ERROR) ,bind()函数前必须添加::,否则,在使用thread头文件后,使用了using namespace std的情况下,会被默认成std::bind,导致编译失败 (1)server #include<WinS...
继续访问
C#winform UDP通信 发送和接收信息
using Systemusing System.Collections.Genericusing System.ComponentModelusing System.Datausing System.Drawingusing System.Linqusing System.Netusing System.Net.Socketsusing System.Text
继续访问
udp多线程 java_多线程以从多个UDP客户端接收数据
我想从不同的客户端接收数据(客户端数量是固定的,比如10),并且每个客户端在5个不同的预定义端口上发送数据,这些端口不会改变 . (例如,客户端1端口5000,5001,5002等) . 所有客户端都可以同时发送数据 . (以上都是固定的)在TCP中说,我可以为我们接受的每个连接创建多个线程,如下所示 . UDP is connectionless,So how can we create ...
继续访问
不同端口间的信息交换-使用udp协议
本文主要内容: 1.套接字(socket)简介; 2.udp简介; 3.udp发送数据及接收数据; 4.模拟qq聊天。 1.套接字(socket)简介 本地可以通过进程PID来唯一标识一个进程,但在网络中这是行不通的。ip地址可以唯一标识网络中的主机,传输层的“协议+端口号”可以唯一标识主机...
继续访问
c语言udp监听多个端口号,多个UDP监听同一个端口
测试结果:客户端的数据总是发给最后一个打开的服务器服务器代码:socket()->setsockopt()->bind()->recvfrom()/sendto()1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #include 91011 int main(int ar...
继续访问
udp接收多个端口的数据
UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层--传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。UDP用来支持那些需要在计算机之间传输数据的网络应用。包括网络视频会议系统在内的众多的客户/服务器模式的网络应用都需要使用UDP协议。UDP协议从问世至今已经被使用了很多年,虽然其最初的光彩已经被一些类似协议所掩盖,但是即使是在今天UDP仍然不失为一项非常实用和可行的网络传输层协议。具体配置过程:1、打开STM32CubeMX,并选择好相应的芯片。文中的芯片为STM32F207VCT6,选择后如下图:
2、配置RCC时钟、ETH、PA8以及使能LWIP;
由于此处我们的开发板硬件上为RMII方式,因此选择ETH-RMII,若有同志的开发板为MII方式,请参考MII的配置方法,此处只针对RMII;
RCC选择外部时钟源,另外勾选MCO1,软件会自动将PA8配置为MCO1模式,该引脚对于RMII方式很重要,用于为PHY芯片提供50MHz时钟;
使能LWIP;
3、时钟树的相关配置,必须保证MCO1输出为50Mhz,如果这个频率不对会导致PHY芯片无法工作;
我这里因为芯片为207VCT6,为了使MCO1输出为50Mhz,做了PLL倍频参数的一些调整,总体如下:(同志们配置时可根据自己的芯片灵活配置,但需保证MCO1的输出为50Mhz)
4、ETH、LWIP、RCC相关参数设置;
至此,比较重要的都在前面了,但是还有一点仍需要注意,即PA8引脚输出速度,几次不成功都是因为这个引脚没注意。
后续的参数设置可以根据同志们自己的需求分别设置,这里给出我的设置供参考;
ETH参数保持默认,但中断勾选一下;
LWIP参数设置如下:(因为我这里是配置UDP服务器,IP选择静态分配)
5、生成工程,做最后的函数修改;
给生成的工程添加UDP服务器的初始化以及端口绑定等相关函数;
我这里直接将之前的官方例程中的UDP服务器文件加进来,如下:
之后将.c文件添加到用户程序,主函数添加Udp的.h头文件;如下:(udp文件的具体内容在后面给出)
6、主函数还需要添加一下几个函数,在这里不对函数作用及实现原理讲解,仅做添加说明。
附:udp_echoserver相关文件内容(该文件为官方的示例程序,版权归官方,此处做转载)
udp_echoserver.c的内容如下:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "lwip/tcp.h"
#include
#include
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define UDP_SERVER_PORT 7 /* define the UDP local connection port */
#define UDP_CLIENT_PORT 7 /* define the UDP remote connection port */
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initialize the server application.
* @param None
* @retval None
*/
void udp_echoserver_init(void)
{
struct udp_pcb *upcb
err_t err
/* Create a new UDP control block */
upcb = udp_new()
if (upcb)
{
/* Bind the upcb to the UDP_PORT port */
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
err = udp_bind(upcb, IP_ADDR_ANY, UDP_SERVER_PORT)
if(err == ERR_OK)
{
/* Set a receive callback for the upcb */
udp_recv(upcb, udp_echoserver_receive_callback, NULL)
}
}
}
/**
* @brief This function is called when an UDP datagrm has been received on the port UDP_PORT.
* @param arg user supplied argument (udp_pcb.recv_arg)
* @param pcb the udp_pcb which received data
* @param p the packet buffer that was received
* @param addr the remote IP address from which the packet was received
* @param port the remote port from which the packet was received
* @retval None
*/
void udp_echoserver_receive_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
/* Connect to the remote client */
udp_connect(upcb, addr, UDP_CLIENT_PORT)
/* Tell the client that we have accepted it */
udp_send(upcb, p)
/* free the UDP connection, so we can accept new clients */
udp_disconnect(upcb)
/* Free the p buffer */
pbuf_free(p)
}
udp_echoserver.h的内容如下:
#ifndef __ECHO_H__
#define __ECHO_H__
void udp_echoserver_init(void)
#endif /* __MINIMAL_ECHO_H */
7、至此,所有的工作完成,编译工程,下载至开发板。由于udp_echoserver中绑定的端口号为7,这里我们通过测试工具测试网络的功能,
欢迎分享,转载请注明来源:夏雨云
评论列表(0条)