基础知识 Socket

网络基础知识

TCP/IP协议

比如A给B发一句你好

这中间发送的过程:

你好转成二进制 -------> 到应用层加包头 App 你好-------> 到传输层TCP App 你好-------> 到IP层 IP TCP App 你好-------> 到链路层 帧头 IP TCP App 你好 帧尾

想要用TCP协议 需要三次握手

SYN表示请求
ACK表示确认

用户向服务器发SYN的包
服务器向用户发SYN-ACK的包
用户在向服务器发送ACK的包

FIN表示结束

用户向服务器发送FIN的包
服务器向用户发送ACK的包
服务器接着向用户发送FIN的包
用户在向服务器发送ACK的包

TCP 安全

UDP 快

Socket

套接字

分客户端和服务端

服务端 抽离出来的概念 可以理解为服务器

​ 实例化

​ 绑定监听端口

​ 设置监听队列

​ while(true){} 循环等待客户端连接 <-----异步加载 客户端什么时候建立联系

​ 接受客户端连接 <-----异步加载 客户端什么时候发消息

​ 接收数据

客户端

​ 连接建立

​ 发送数据

​ 关闭

MSDN 里可以搜索System.Net.Sockets.Socket

在这里插入图片描述
在这里插入图片描述

SocketTool

using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SocketTool {
    
    #region Singleton
    private static SocketTool instance;
    
    public static SocketTool GetInstance(){
        if(instance == null){
            instance = new SocketTool();
        }
        return instance;
    }
    
    private SocketTool(){}
    #endregion
    
    #region Server 服务端
    //服务端套接字
    private Socket serverSocket;
    //服务端上层回调
    private Action<string> serverCallback;
    //已经连接的客户端
    private Distionary<IPAddress,Socket> connectedClient;
    //服务端消息缓存
	private byte[] serverBuffer;
    
    //初始化服务端
	public void ServerInit(Action<string> serverCallback){
        //设置委托回调
        this.serverCallback = serverCallback;
        //实例化字典
        connectedClient = new Distionary<IPAddress,Socket>();
        //实例化缓存长度
        serverBuffer = new byte[1024];
        //实例化Socket对象【TCP】
        serverSocket = new Socket(AddressFamily.InterNetwork,/*地址族:存的是IPV4*/
                      SocketType.Stream,/*双向读写流*/,ProtocolType.Tcp/*传输层协议类型*/);
        
        //实例化Socket对象【UDP】
        //serverSocket = new Socket(AddressFamily.InterNetwork,/*地址族:存的是IPV4*/
        //              SocketType.Dgram,/*数据报*/,ProtocolType.Udp/*传输层协议类型*/);
        
        serverCallback("服务端创建完毕");
        
        //创建IP网络节点									0-65532 防止知名端口被占用10000以前的不用
        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any,12345);
        //绑定监听端口
        serverSocket.Bind(ipEndPoint);
        
        serverCallback("网络结点绑定完毕");
        
        //设置监听队列       //监听的越多子线程越多
        serverSocket.Listen(5);
        //异步接受客户端的连接请求
        serverSocket.BeginAccept(ServerAccept,serverSocket);
        
        serverCallback("异步接受请求开始");
        
    }
    
    //委托 异步接受请求后,接受到客户端的回调
    private void ServerAccept(IAsyncResult ar)
    {
        //获取到异步接受的监听
        Socket listener = ar.AsyncState as Socket;
        //结束异步接受
        Socket acceptClient = listener.EndAccept(ar);
        //获取该客户端的本地地址
        IPAddress clientLocalAddress = (acceptClient.LocalEndPoint as IPEndPoint).Address;
        //将当前客户端的Socket保存
        connectedClient.Add(clientLocalAddress,acceptClient);
        
        serverCallback("异步接受请求结束" + acceptClient.LocalEndPoint);
        
        //开始对该客户端进行异步的消息接收
        acceptClient.BeginReceive(serverBuffer,/*消息缓存*/0,/*消息接收的偏移量*/
                                  serverBuffer.Length,/*消息接收长度*/SocketFlags.None,/*消息接收的特殊标记*/
                                 ServerReceive,/*消息接受到后的回调*/acceptClient/*状态信息*/);
        
        serverCallback("异步消息接收开始");
        
        //尾递归 【继续接受其他客户端的连接请求】
        serverSocket.BeginAccept(ServerAccept,serverSocket);
    }
    
    //异步接收消息的回调
    private void ServerReceive(IAsyncResult ar)
    {
        //获取异步状态
        Socket listener = ar.AsyncState as Socket;
        //收到消息的字节数
        int count = listener.EndReceive(ar);
        
        serverCallback("异步消息接收结束,接收了" + count + "个字节");
        
        //将收到的字节流转换成字符串
        string msg = UTF8Encoding.UTF8.GetString(serverBuffer); 
        
        serverCallback("接收到的消息为" + msg);
        
        //清空字节流
        serverBuffer = new byte[1024];
        //尾递归
        listener.BeginReceive(serverBuffer,/*消息缓存*/0,/*消息接收的偏移量*/
                                  serverBuffer.Length,/*消息接收长度*/SocketFlags.None,/*消息接收的特殊标记*/
                                 ServerReceive,/*消息接受到后的回调*/listener/*状态信息*/);
    }
    
   	#endregion
            
    #region Client 客户端
    //客户端套接字
    private Socket clientSocket;
    //客户端缓存
	private byte[] clientBuffer;
    //客户端消息回调
    private Action<string> clientCallback;
    
    //客户端连接
	public void ClientConnect(string serverIP,int serverPort,Action<string> clientCallback)
    {
        //设置回调
        this.clientCallback = clientCallback;
        //实例化Socket
        clientSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
        
        clientCallback("客户端创建完毕");
        
        //组装网络结点
        IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(serverIP),serverPort);
        //连接服务器
        clientSocket.BeginConnect(ipEndPoint,ClientConnected,clientSocket);
        
        clientCallback("客户端异步连接服务器完毕");
    }
    
    //客户端连接成功
    private void ClientConnected(IAsyncResult ar)
    {
        Socket listener = ar.AsyncState as Socket;
        //结束连接
        listener.EndConnect(ar);
        
        clientCallback("客户端连接服务器成功");
    }
    
    //客户端发送消息
    public void ClientSend(string msg)
    {
        //将消息转换为字节数组,保存到buffer
        clientBuffer = UTF8Encoding.UTF8.GetBytes(msg);
        //发消息
        clientSocket.BeginSend(clientBuffer,0,clientBuffer.Length,SocketFlags.None
                              ClientSendSuccess,clientSocket);
        
        clientCallback("客户端向服务器发送消息" + msg);
    }
    
    private void ClientSendSuccess(IAsyncResult ar)
    {
        Socket listener = ar.AsyncState as Socket;
        //结束发送
        int count = listener.EndSend(ar);
        clientCallback("客户端成功发送消息" + count + "个字节");
        
    }
   	#endregion
        
        
    #region Socket Dispose
        
    public void SocketDispose()
    {
        if(serverSocket != null){
            serverSocket.Close();
            serverSocket = null;
        }
        
        if(clientSocket != null){
            clientSocket.Disconnect(true);
            clientSocket.Close();
            clientSocket = null;
        }
    }
   	#endregion

}

OnGUI

using UnityEngine;

public class SocketDemo : MonoBehaviour {
	private string textFieldText = "需要初值写这里";
	
	public void OnGUI(){
	
		//手动布局【GUI】
		if(GUI.Button(new Rect(300,100,200,50),"登录")){
			Debug.Log("登录被点击了");
		}
		
		textFieldText = GUI.TextField(new Rect(100,300,200,50),textFieldText);
		
		
		//自动布局【GUILayout】
		
		GUILayout.Button("注册");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值