我开发了一些多人游戏。并使用TcpClient
。
我有此客户端代码:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class TCPClient : MonoBehaviour {
#region private members
private TcpClient socketConnection;
private Thread clientReceiveThread;
private long timestamp;
#endregion
// Use this for initialization
void Start () {
ConnectToTcpServer();
}
/// <summary>
/// Setup socket connection.
/// </summary>
private void ConnectToTcpServer () {
try {
clientReceiveThread = new Thread (new ThreadStart(ListenForData));
clientReceiveThread.IsBackground = true;
clientReceiveThread.Start();
}
catch (Exception e) {
Debug.Log("On client connect exception " + e);
}
}
/// <summary>
/// Runs in background clientReceiveThread; Listens for incomming data.
/// </summary>
private void ListenForData() {
try {
socketConnection = new TcpClient(MainController.instance.connectIp.text, 8052);
Byte[] bytes = new Byte[1024];
while (true) {
// Get a stream object for reading
using (NetworkStream stream = socketConnection.GetStream()) {
int length;
// Read incomming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
var incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length);
// Convert byte array to string message.
string serverMessage = Encoding.ASCII.GetString(incommingData);
Debug.Log("server message received as: " + serverMessage);
Dispatcher.Invoke(() =>
{
string[] position = serverMessage.Split(';');
MainController.instance.SetBallPosition(float.Parse(position[0]), float.Parse(position[1]));
});
}
}
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
public IEnumerator ThisWillBeExecutedOnTheMainThread(string message) {
yield return null;
}
/// <summary>
/// Send message to server using socket connection.
/// </summary>
public void SendData(string message) {
if (socketConnection == null) {
return;
}
try {
// Get a stream object for writing.
NetworkStream stream = socketConnection.GetStream();
if (stream.CanWrite) {
// Convert string message to byte array.
byte[] clientMessageAsByteArray = Encoding.ASCII.GetBytes(message);
// Write byte array to socketConnection stream.
stream.Write(clientMessageAsByteArray, 0, clientMessageAsByteArray.Length);
Debug.Log("Client sent his message - should be received by server");
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
}
对于服务器:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class TCPServer : MonoBehaviour {
#region private members
/// <summary>
/// TCPListener to listen for incomming TCP connection
/// requests.
/// </summary>
private TcpListener tcpListener;
/// <summary>
/// Background thread for TcpServer workload.
/// </summary>
private Thread tcpListenerThread;
/// <summary>
/// Create handle to connected tcp client.
/// </summary>
private TcpClient connectedTcpClient;
#endregion
// Use this for initialization
void Start () {
// Start TcpServer background thread
tcpListenerThread = new Thread (new ThreadStart(ListenForIncommingRequests));
tcpListenerThread.IsBackground = true;
tcpListenerThread.Start();
}
/// <summary>
/// Runs in background TcpServerThread; Handles incomming TcpClient requests
/// </summary>
private void ListenForIncommingRequests () {
try {
// Create listener on localhost port 8052.
tcpListener = new TcpListener(IPAddress.Any, 8052);
tcpListener.Start();
Debug.Log("Server is listening");
Byte[] bytes = new Byte[1024];
while (true) {
using (connectedTcpClient = tcpListener.AcceptTcpClient()) {
// Get a stream object for reading
using (NetworkStream stream = connectedTcpClient.GetStream()) {
int length;
// Read incomming stream into byte arrary.
while ((length = stream.Read(bytes, 0, bytes.Length)) != 0) {
var incommingData = new byte[length];
Array.Copy(bytes, 0, incommingData, 0, length);
// Convert byte array to string message.
string clientMessage = Encoding.ASCII.GetString(incommingData);
Debug.Log("client message received as: " + clientMessage);
}
}
}
}
}
catch (SocketException socketException) {
Debug.Log("SocketException " + socketException.ToString());
}
}
/// <summary>
/// Send message to client using socket connection.
/// </summary>
public void SendData(string message) {
if (connectedTcpClient == null) {
return;
}
try {
// Get a stream object for writing.
NetworkStream stream = connectedTcpClient.GetStream();
if (stream.CanWrite) {
// Convert string message to byte array.
byte[] serverMessageAsByteArray = Encoding.ASCII.GetBytes(message);
// Write byte array to socketConnection stream.
stream.Write(serverMessageAsByteArray, 0, serverMessageAsByteArray.Length);
stream.Flush();
Debug.Log("Server sent his message - should be received by client");
}
}
catch (SocketException socketException) {
Debug.Log("Socket exception: " + socketException);
}
}
}
我面临下一个问题。我在对象的Update
中发送消息以同步客户端上的位置。我以简单的方式进行操作,只需将x
和z
坐标放入带有;
分隔符的字符串中。收到消息后,我将其拆分并取得坐标。但是在客户端上,我可以收到下一条消息0;00;00;00;00;00;00;00;00;00;00;00;00;00;0
。消息只是粘在一起,无法解析。有人可以帮我吗?我如何(如果可能)拆分邮件,一一发送和接收?
谢谢。