网络基础(五)异步模式,客户端编写
1.客户端程序也使用BeginReceive实现异步接收。因为c#使用线程池处理异步调用,所以ReceiveCb并不在主线程中,但只有主线程方能设置UI组件,因此ReceiveCb之设置字符串recvStr,再由主线程Update方法处理UI组件。
2.编写连接的方法Connetion,当“button”按钮被按下时,该方法被调用。它依照socket - connect 的流程连接服务端,然后再调用BeginReceive开启异步接收。
3.当收到服务端发来的消息时,异步接收回调ReceiveCb将被调用。它显示解析服务端的消息,将聊天语句存入recvStr中,然后再调用BeginReceive开启下一次异步接收。
4.编写发送消息的方法Send,当点击界面“send button”时,该方法被调用。调用socket.Send方法将textInput的内容发送给服务端。
=====unity界面如下:
server输入ip和端口号,点击“button”,获取客户端ip和端口号,返回在New Text处;
在下方输入框输入“聊天内容”,点击“send button”发送数据给服务端,并广播给连接的客户端,数据显示在recvText处。
=====客户端代码如下
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using UnityEngine.UI;
public class Asynet : MonoBehaviour {
//服务器IP和端口
public InputField hostInput;
public InputField portInput;
//显示客户端收到的消息
public Text recvText;
public string recvStr;
//显示客户端IP和端口
public Text clientText;
//聊天输入框
public InputField textInput;
//Socket和接收缓冲区
Socket socket;
const int BUFFER_SIZE = 1024;
public byte[] readBuff = new byte[BUFFER_SIZE];
//因为只有主线程能够修改UI组件的属性
//因此在update里更换文本
void Update()
{
recvText.text = recvStr;
}
//连接
public void Connetion()
{
//清理text
recvText.text = " ";
//Socket
socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
//Connect
string host = hostInput.text;
int port = int.Parse (portInput.text);
socket.Connect (host, port);
clientText.text = "客户端地址:" + socket.LocalEndPoint.ToString ();
//Recv
socket.BeginReceive(readBuff,0,BUFFER_SIZE,SocketFlags.None,ReceiveCb,null);
}
//接收回调 (当收到服务端发来的消息时,异步接收回调ReceiveCb将被调用。先是解析服务端的消息,将聊天语句存入recvStr中,然后再调用BeginReceive开启下一次异步接收。)
private void ReceiveCb(IAsyncResult ar)
{
try
{
//count是接收数据的大小
int count = socket.EndReceive(ar);
//数据处理
string str = System.Text.Encoding.Default.GetString(readBuff,0,count);
if (recvStr.Length >300) recvStr=" ";
recvStr += str +"\n";
//继续接收
socket.BeginReceive(readBuff,0,BUFFER_SIZE,SocketFlags.None,ReceiveCb,null);
}
catch(Exception e)
{
recvText.text += "连接已经断开";
socket.Close ();
}
}
public void Send()
{
string str = textInput.text;
byte[] bytes = System.Text.Encoding.Default.GetBytes(str);
try
{
socket.Send(bytes);
}
catch(SocketException e)
{
Debug.LogError (e.Message);
}
}
}
====添加组件,设置属性参数
1.Canvas添加组件,设置属性
2.butto按钮要添加对应方法
3.send button 要添加对应方法
=====开始调试
启动服务端,然后开两个客户端,点击“button”连接服务端,然后输入数据进行发送,两个客户端都可展示数据(暂时只启动了一个客户端进行截图)