Socket UPD接收数据出现乱码

本文展示了一个使用Java实现的简单UDP通信示例,包括如何发送控制指令(如关闭门禁)到指定服务器及端口,并接收反馈。该示例通过DatagramSocket进行网络通信,利用JSON格式组织数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.xu.servlet;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

//发送请求的代码
public class Snippet
{
	public static void main(String[] args)
	{
		System.out.println("---------");
		Snippet snippet = new Snippet();
		
		
		snippet.Test();
	}
	
	
	public void Test()
	{
		
		//1、创建socket对象,通过DatagramSocket对象
        DatagramSocket ds = null;
		try
		{
			ds = new DatagramSocket();
			
		} catch (SocketException e) 
		{
			e.printStackTrace();
		}
        String serverIP = "";
        String socketPort ="";
        JSONObject jsonObject = new JSONObject();
        try 
        {
			/*jsonObject.put("type", "openDoor");
	        jsonObject.put("doorId", "1");
	        jsonObject.put("interval", "20");*/

			jsonObject.put("type", "closeDoor");
	        jsonObject.put("doorId", "1");
	        jsonObject.put("interval", "20");
		} catch (JSONException e1) {
			e1.printStackTrace();
		}

        //2、确定数据,并封装成数据包
        byte[]  data = jsonObject.toString().getBytes();
        DatagramPacket dp = null;
		try 
		{
			dp = new DatagramPacket(data, data.length, InetAddress.getByName("192.168.32.24"), 8086);
			
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}

        //3、通过scoket服务,将已有的数据发送出去,通过send方法
        try {
        	
        	System.out.println(" dp =  "+ dp);
			ds.send(dp);
		} catch (IOException e) 
        {
			e.printStackTrace();
		}
        ds.close();
	}
}
//接收数据	
class AccZonePersonSaveThread extends Thread
	{

		@Override
		public void run()
		{
			 DatagramSocket ds = null;

			System.out.println("---------");
			try
			{
				ds = new DatagramSocket(8088);
			}
			catch (SocketException e1)
			{
				e1.printStackTrace();
			}
			while (true)
			{
				try
				{
					 //2、定义数据包,用于存储数据
				    byte[] buf = new byte[1024];
				    DatagramPacket dp = new DatagramPacket(buf, buf.length);
				
				    //3、通过服务的receive方法,接收数据并存入数据包中
						ds.receive(dp);
				
				    //4、通过数据包中的方法,获取其中的数据。
				    String ip = dp.getAddress().getHostAddress();
				    int port = dp.getPort();
				    String data = new String(dp.getData(),"GBK");
				    System.out.println("ip = " + ip + ": " + port + ":   " + data);
				  
				}
				catch (SocketException e)
				{
					e.printStackTrace();
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
				   
			}
		
			
		}
		
	}
接收的时候加上
 String data = new String(dp.getData(),"GBK");

就可以了


<think>好的,用户想在麒麟系统上使用Unity进行UDP通信。首先,我需要理解UnityKylin系统在这方面的支持情况。麒麟系统是基于Linux的,所以可能需要参考Linux下的UDP通信方法。Unity通常使用C#进行开发,所以得考虑如何在C#中实现UDP客户端。 首先,Unity中的网络通信通常用C#的Socket类。UDP是无连接的,所以不需要建立长连接,只需要发送接收数据报。用户需要在Unity中创建一个UDP客户端,然后麒麟系统上运行一个UDP服务端。可能需要检查麒麟系统的防火墙设置,确保端口开放。 然后,麒麟系统作为服务端,可以使用nc(netcat)工具来监听UDP端口,比如用`nc -ul 8080`命令。这样Unity客户端发送的数据就能被接收。另外,用户可能需要处理数据的编码解码,比如将字符串转换为字节数组。 还要考虑异步处理,避免Unity主线程阻塞。使用BeginReceiveEndReceive方法来实现异步接收。同时,异常处理也很重要,比如处理SocketException。 另外,用户可能遇到的问题包括端口未开放、IP地址错误、数据格式不正确等。需要指导用户如何检查这些点,比如使用lsof命令查看端口监听情况,或者用nc测试连通性。 最后,可能需要提供示例代码,展示Unity客户端Kylin服务端的实现步骤,确保代码符合C#Unity的规范,同时适配Linux环境。</think>### 在 Unity 中通过 UDP 协议与 Kylin 系统通信的实现步骤 #### 1. Unity 客户端实现 ```csharp using System; using System.Net; using System.Net.Sockets; using System.Text; using UnityEngine; public class UDPClient : MonoBehaviour { public string serverIP = "127.0.0.1"; public int serverPort = 8080; private UdpClient client; void Start() { // 创建UDP客户端(不绑定本地端口) client = new UdpClient(); client.Connect(serverIP, serverPort); // 发送测试数据 SendMessage("Hello Kylin from Unity"); // 启动异步接收 client.BeginReceive(ReceiveCallback, null); } void SendMessage(string message) { byte[] data = Encoding.UTF8.GetBytes(message); client.Send(data, data.Length); } private void ReceiveCallback(IAsyncResult ar) { try { IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0); byte[] receivedBytes = client.EndReceive(ar, ref remoteEP); string receivedMsg = Encoding.UTF8.GetString(receivedBytes); Debug.Log($"Received from Kylin: {receivedMsg}"); // 继续监听下一个消息 client.BeginReceive(ReceiveCallback, null); } catch (SocketException e) { Debug.LogError($"Socket error: {e}"); } } void OnDestroy() { if (client != null) client.Close(); } } ``` #### 2. Kylin 系统服务端配置 在麒麟系统上使用`nc`工具监听UDP端口: ```bash # 安装netcat(若未预装) sudo apt install netcat # 启动UDP服务端监听8080端口 nc -ul -k 8080 ``` *参数说明:* - `-u`:启用UDP模式 - `-l`:监听模式 - `-k`:保持监听(持续接收多个数据包) #### 3. 关键配置注意事项 1. **网络可达性验证** ```bash # 在Kylin系统查看端口监听状态 lsof -i :8080 ``` 预期输出应包含`nc`进程的UDP监听状态[^3]。 2. **防火墙配置** ```bash # 开放UDP端口(麒麟系统基于Linux) sudo ufw allow 8080/udp ``` 3. **跨平台数据编码** - 统一使用UTF-8编码 - 建议添加数据包头标识(如消息长度) - 推荐使用JSON格式进行结构化数据传输 4. **调试技巧** ```bash # 使用tcpdump抓包验证 sudo tcpdump -i any udp port 8080 -vv -X ``` #### 4. 增强实现建议 1. **超时重传机制** ```csharp // 在Unity客户端添加超时检测 System.Timers.Timer timeoutTimer = new System.Timers.Timer(2000); timeoutTimer.Elapsed += (s, e) => { Debug.Log("Timeout, resending..."); SendMessage(lastSentMessage); }; ``` 2. **数据校验** ```csharp // 添加CRC校验 byte[] AddChecksum(byte[] data) { byte checksum = 0; foreach (byte b in data) checksum ^= b; byte[] newData = new byte[data.Length + 1]; Array.Copy(data, 0, newData, 0, data.Length); newData[data.Length] = checksum; return newData; } ``` 3. **多线程处理** ```csharp // 使用Loom插件处理跨线程回调 Loom.QueueOnMainThread(() => { Debug.Log($"Received: {receivedMsg}"); }); ``` #### 5. 常见问题排查表 | 现象 | 检查点 | 调试命令 | |----------------------|--------------------------------|----------------------------| | 数据无法接收 | 防火墙状态 | `sudo ufw status` | | 间歇性丢包 | 网络带宽占用 | `iftop -i eth0` | | 数据乱码 | 编解码一致性 | `hexdump -C received.bin` | | 连接超时 | 路由可达性 | `traceroute 目标IP` |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值