分身有术:异步和多路复用

异步客户端

在Unity中,执行Start、Update方法的线程是主线程,更新UI也是主线程。将同步代码,改成异步代码,需要分别在原名称前面加上Begin和End(如BeginConnect和EndConnect)。

异步Connect

Public IAsyncResult BeginConnect{
	string host,
	int post,
	AsyncCallback requestCallback,
	object state
}
public void EndConnect{
	IAsyncResult asyncResult
}

其中requestCallback是回调函数,形式是void ConnectCallback(IAsyncResult ar),因为EndConnect必定是要在BeginConnect的回调函数中写入的,才能实现对接受完毕的处理,而EndConnect需要IAsyncResult类型的参数,所以需要与回调函数的参数保持一致,而ConnectCallback的参数又是从哪里来的呢,从第四个参数state来,这是一个用户自定义的量socket,在回调函数中可以通过ar.AsyncState得到。

异步Receive

这部分是类似的

public IAsyncResult BeginReceive{
	byte[] buffer,
	int offset,
	int size,
	SocketFlags socketFlags,
	AsyncCallback callback,
	object state
}
public int EndReceive{
	IAsyncResult asyncResult
}

异步Send

这部分也类似

public IAsyncResult BeginSend{
	byte[] buffer,
	int offset,
	int size,
	SocketFlags socketFlags,
	AsyncCallback callback,
	object state
}
public int EndSend{
	IAsyncResult asyncResult
}

异步客户端代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net.Sockets;
using UnityEngine.UI;
using System;

public class Echo : MonoBehaviour {

	//定义套接字
	Socket socket;
	//UGUI
	public InputField InputFeld;
	public Text text;
	//接收缓冲区
	byte[] readBuff = new byte[1024]; 
	string recvStr = "";
	//点击连接按钮
	public void Connetion()
	{
		//Socket
		socket = new Socket(AddressFamily.InterNetwork,
			SocketType.Stream, ProtocolType.Tcp);
		//Connect
		socket.Connect("127.0.0.1", 8888);
		//socket.BeginConnect("127.0.0.1", 8888, ConnectCallback, socket);
	}

	//Connect回调
	public void ConnectCallback(IAsyncResult ar){
		try{
			Socket socket = (Socket) ar.AsyncState;
			socket.EndConnect(ar);
			Debug.Log("Socket Connect Succ ");
			socket.BeginReceive( readBuff, 0, 1024, 0,
				ReceiveCallback, socket);
		}
		catch (SocketException ex){
			Debug.Log("Socket Connect fail" + ex.ToString());
		}
	}

	//Receive回调
	public void ReceiveCallback(IAsyncResult ar){
		try {
			Socket socket = (Socket) ar.AsyncState;
			int count = socket.EndReceive(ar);
			string s = System.Text.Encoding.UTF8.GetString(readBuff, 0, count);
			recvStr = s + "\n" + recvStr;

			socket.BeginReceive( readBuff, 0, 1024, 0,
				ReceiveCallback, socket);
		}
		catch (SocketException ex){
			Debug.Log("Socket Receive fail" + ex.ToString());
		}
	}

	//点击发送按钮
	public void Send()
	{
		//Send
		string sendStr = InputFeld.text;
		byte[] sendBytes = System.Text.Encoding.Default.GetBytes(sendStr);
		socket.BeginSend(sendBytes, 0, sendBytes.Length, 0, SendCallback, socket);
	}

	//Send回调
	public void SendCallback(IAsyncResult ar){
		try {
			Socket socket = (Socket) ar.AsyncState;
			int count = socket.EndSend(ar);
			Debug.Log("Socket Send succ " + count);
		}
		catch (SocketException ex){
			Debug.Log("Socket Send fail" + ex.ToString());
		}

	}


	public void Update(){
		text.text = recvStr;
	}
}

这只是将第一章的同步代码改成了异步代码,虽然实现了异步的功能,但是还有很多问题。

异步服务端

为了管理客户端信息,需要引入一个类记录客户端的状态,以后还有后续的信息也会加到这个里面,比如hp值,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值