基于Socket的通信小实例
来源:互联网 发布:如何看待纽约 知乎 编辑:程序博客网 时间:2024/05/16 10:44
距离上次更博已经好长的时间了,上班了工作了,确实空闲下来的时间少了,然而我更多的在思考在于,写些啥,有啥东西是可以放进博客里的,千篇一律的教程亦或是自己研究出来的东西,我想更应该是后者吧,不然我这博客也是搭得没意思。
话不多说,今天我们来了解下Socket相关的知识,可以说的上是基础,做了点小通信(其实也简单啦)~
实现效果
先说整个实例在实现效果上,由于本实例只是对Socket相关的使用做了个基本的测试,所以在效果上确实是差强人意,也就不上图了,大体的效果描述就是:在Unity搭建的客户端,创建的UI按钮上进行点击,给服务端进行消息的发送,而后服务端返回相应的消息,不同的消息发送有不同的回应而已。
效果不重要,毕竟才基础,里面的原理才是我们需要了解的~
服务端搭建
这里的服务端,博主采取的是通过VS创建控制台程序,在电脑上开启服务端代码,主程序入口如下
Program.cs
using System; class Program { static void Main(string[] args) { Server server = new Server("127.0.0.1",8899); server.Start(); Console.ReadKey(); } }
其实主程序无非就是创建了服务类,开启服务而已,而这里的服务类就是Socket相关使用的主体了
Server.cs
using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; class Server { private Socket serverSocket; private Socket clientSocket; private IPAddress ipAddress; private IPEndPoint ipEndPoint; private List<Client> clientList = new List<Client>(); public Server(string ip,int port) { //创建Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //声明ip地址和端口号 this.ipAddress = IPAddress.Parse(ip); this.ipEndPoint = new IPEndPoint(ipAddress, port); } public void Start() { //Socket绑定IP和端口号 serverSocket.Bind(ipEndPoint); //Socket开始监听 serverSocket.Listen(0); Console.WriteLine("服务器已经启动"); //客户端接入 serverSocket.BeginAccept(AcceptCallback,null); } private void AcceptCallback(IAsyncResult ar) { clientSocket = serverSocket.EndAccept(ar); //获取客户端名称 string clientName = clientSocket.RemoteEndPoint.ToString(); Client client = new Client(clientSocket, clientName); client.Start(); Console.WriteLine(clientName + "已经登录。。。"); clientList.Add(client); //继续循环监听客户端的连接 serverSocket.BeginAccept(AcceptCallback, null); } }
Server类的主要功能无非就是开启个Socket绑定确定的IP和端口,时刻监听客户端的连接。程序在这里采取的是异步方式,之所以代码上没有明显的线程调用,是因为在采用了封装好的API,像 BeginXXX 这样的函数,为了能够循环监听客户端的连接也是在AcceptCallback里面继续开启客户端的监听,大体的逻辑是这样。
而这里的Client类可不是代表实际意义上的客户端,这里只是对客户端进行的相关管理,主要是对客户端的消息发送和接收进行着处理,之所以采取两个类的方式,也是受到面向对象思想的影响,同样便于代码的管理。
Client.cs
using System; using System.Text; using System.Net.Sockets; class Client { private Socket clientSocket; private string clientName; private byte[] recieveData; public Client(Socket client,string clientName) { this.clientSocket = client; this.clientName = clientName; recieveData = new byte[clientSocket.ReceiveBufferSize]; } public void Start() { clientSocket.BeginReceive(recieveData,0, clientSocket.ReceiveBufferSize,SocketFlags.None, RecieveCallback, null); } //接收客户端的消息 private void RecieveCallback(IAsyncResult ar) { try { //接收到的数据长度 int count = clientSocket.EndReceive(ar); //防止客户端异常退出 if (count == 0) { clientSocket.Close(); return; } //对接收到的数据进行处理 string msgRec = Encoding.UTF8.GetString(recieveData, 0, count); HandleResponse(msgRec); //输出到控制台 Console.WriteLine(msgRec); //循环接收客户端发送过来的数据 clientSocket.BeginReceive(recieveData, 0, clientSocket.ReceiveBufferSize, SocketFlags.None, RecieveCallback, null); } catch (Exception) { if (clientSocket != null) { clientSocket.Close(); return; } } } //对客户端返回过来的数据进行处理 private void HandleResponse(string data) { if (data.Equals("hello")) { SendMessage("hello too"); }else if (data.Equals("haha")) { SendMessage("heihei"); } } //发送消息给客户端 private void SendMessage(string data) { byte[] msgData = Encoding.UTF8.GetBytes(data); clientSocket.Send(msgData); } }
服务器端对客户端发出的请求是在对消息解析后才处理的,也就是我们的HandleResponse函数里面,这里只是简单的对客户端发送过来的字符串进行简单的if else判断而已~
客户端创建
相对服务器端的构建,客户端算是简单了许多,这里也就只有一个类来测试的。
Client.cs
using UnityEngine; using System.Text; using System.Net.Sockets; using System.Net; using System; using UnityEngine.UI; public class Client : MonoBehaviour { private Socket clientSocket; private byte[] recieveData; private Button btn1; private Button btn2; // Use this for initialization void Start () { InitNet(); btn1 = transform.Find("Btn1").GetComponent<Button>(); btn2 = transform.Find("Btn2").GetComponent<Button>(); btn1.onClick.AddListener(() => { SendMsg("hello"); }); btn2.onClick.AddListener(() => { SendMsg("haha"); }); } private void InitNet() { // 首先声明一个Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //申明IP和端口号 IPAddress iPAddress = IPAddress.Parse("127.0.0.1"); IPEndPoint iPEndPoint = new IPEndPoint(iPAddress, 8899); //连接服务器端 clientSocket.Connect(iPEndPoint); //接收服务端发送过来的消息 recieveData = new byte[clientSocket.ReceiveBufferSize]; clientSocket.BeginReceive(recieveData, 0, clientSocket.ReceiveBufferSize, SocketFlags.None, RevieveCallback, null); } private void RevieveCallback(IAsyncResult ar) { int count = clientSocket.EndReceive(ar); string msgRec = Encoding.UTF8.GetString(recieveData, 0, clientSocket.ReceiveBufferSize); //输出信息 Debug.Log(msgRec); recieveData = new byte[clientSocket.ReceiveBufferSize]; clientSocket.BeginReceive(recieveData, 0, clientSocket.ReceiveBufferSize, SocketFlags.None, RevieveCallback, null); } private void SendMsg(string data) { byte[] sendMsg = Encoding.UTF8.GetBytes(data); clientSocket.Send(sendMsg); } }
在客户端初始Socket,确认IP和端口号就能连上服务器了,然后通过Unity的组件进行消息的发送,然后接收相关消息,流程一步了然,简直不要太简单~
源码地址
源码工程已上传Github了,在这里
总结
通过这个小的实例可以了解到Socket的基本编程,以及简单的网络通信,当然这只是在局域网下能够通信哈,而后博主也是会加大难度,基于此开发一个网络游戏,在广域网下也能完美运行(当然现在服务器都没有233333)
就这么多,白了个白~
- 基于Socket的通信小实例
- 基于Socket通信的小实例(二)
- 基于Java NIO 的socket通信实例
- Socket通信入门小实例
- Android中基于protobuf的socket通信的实例
- AVA实现基于Tcp协议的简单Socket通信实例
- 基于Tcp协议的简单Socket通信实例(JAVA)
- 基于Tcp协议的简单Socket通信实例(JAVA)
- 基于TCP协议的Socket通信实例(JAVA)
- java实现基于TCP的socket通信实例(客户端)
- java Socket客户端服务端通信小实例
- 基于Socket通信的聊天室
- 基于UDP的socket通信
- 基于android的Socket通信
- 基于TCP的Socket通信
- 基于android的Socket通信
- 基于android的Socket通信
- 基于android的Socket通信
- Connected Graph POJ1737 高精度
- 知道这20个正则表达式,能让你少写1,000行代码
- 滴滴笔试-青蛙走地下迷宫问题
- Linux系统常用命令
- tomcat7在myeclipse中启动不了 出现严重: Error waiting for multi-thread deployment of directories to completehos
- 基于Socket的通信小实例
- B
- android studio一个编译时的bug
- PAC成本数据模型
- JNA调用本地dll
- 《C++ Primer》第五版课后习题解答_第三章(1)(01-05)
- stl之rope大法好及可持久化并查集用法
- svm+hog
- 实现xlistview+xutils展示数据之后点击item跳转页面显示图片缩放和放大