C#实践炸飞机socket通信

一、前言

  • 最近老师要求做课设,实现一个 “炸飞机” 游戏,我是负责UI界面实现和Socket通信实现的 , 在这里想总结一下我实现Socket的具体过程,对其中的产生的问题和实现的方法进行进行分析 。由于我是第一次具体实现Socket通信 , 所以走了不少弯路,请教了许多人,其中尤其是我的舍友,对我帮助很大 。
二、实现思路我采用的模式是C/S模式(客户端-服务器模式),并且是TCP模式
  • 首先是单例化对象,对客户端和服务器都进行了单例化 , 确保炸飞机时只有一个客户端和一个服务器(因为这个游戏是1V1嘛);
  • 然后对客户端的和服务器端 send() 和 receive() 函数进行编写,要注意的一点是:这里不能盲目照搬网络上的代码,其代码使用场景简单,通常是发送一次接收一次(或者是发送一次一直接收),总之对本项目而言是不能适用的;
  • 再然后是封装类,封装好之后在其他命名空间中调用接口
三、具体代码客户类代码1. 主体代码部分using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Net.Sockets;using System.Net;using System.Threading;namespace TestBoom{class Client//这是封装好的客户端类{public String receivestr = null;private static Clientclient;private Socket ClientSocket;private Client(string ip1, int port1){ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);Init(ip1, port1);}public static Client clientsocket(string ip1,int port1){if (client == null){client = new Client(ip1,port1);}return client;}private void Init(string ip1, int port1){IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse(ip1), port1);ClientSocket.Connect(iPEnd);Thread reciveThread = new Thread(Recive);reciveThread.IsBackground = true;reciveThread.Start();}public void Recive(){while (true){byte[] Btye = new byte[1024];ClientSocket.Receive(Btye);receivestr = Encoding.UTF8.GetString(Btye,0,3);if (receivestr[0] == '0'){Console.WriteLine($"接受对方了轰炸位置{receivestr}");}else if(receivestr[0]=='1'){Console.WriteLine($"接受轰炸位置结果{receivestr}");}}}public void Send(int i,int x,int y){string str =Convert.ToString(i)+Convert.ToString(x) + Convert.ToString(y);byte[] Btye = Encoding.UTF8.GetBytes(str);ClientSocket.Send(Btye);if (str[0] == '0'){Console.WriteLine($"已发送轰炸位置 {str}");}else if (str[0] == '1'){Console.WriteLine($"已发送对方轰炸位置结果{str}");}}}}2. 具体分析:1. 首先这个游戏我们必须要知道的一点是我们想要实现两台电脑之间的交互,就必须使用ip和端口进行连接,而想要进行连接就必须使用一个实例化的对象(在这里我没有体现出来,因为实例化对象在另一个from中,在按钮事务响应的函数中进行实例化) , 而且在这个游戏中,实例化对象必须是单例模型,原因之前提到过,那么实例化对象就必须包含单例化的过程;
public String receivestr = null;//receivestr是接受函数中接收到对方的传输过来的信息,后面用到private static Clientclient;//单例化对象所需要的对象private Socket ClientSocket;//Socket类的一个实例化对象private Client(string ip1, int port1)//Client()客户端构造函数{ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);Init(ip1, port1);}public static Client clientsocket(string ip1,int port1) //单例化实现函数{if (client == null)//如果实例化对象不存在,则创建一个{client = new Client(ip1,port1);}return client;//如果存在,则直接返回存在的那个对象,这样便实现了单例化}private void Init(string ip1, int port1)//初始化,用于进行客户端和服务器端的连接{IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse(ip1), port1);ClientSocket.Connect(iPEnd);Thread reciveThread = new Thread(Recive);reciveThread.IsBackground = true;reciveThread.Start();}2. 其次在连接妥当之后,必须进行信息传输,如果而现在假定客户端时先手 , 则要进行 send() 函数的调用 , 在函数中你可以发送任意的数据 , 但必须时btye数组(因为在物理层传输数据是发送的是比特,发送到对方物理层会进行解析还原,但是这些东西C#的Socket类已经封装好了 , 我们调用接口即可),需要注意的是在使用 send() 的时候必须调用(这个之后再详细说);
public void Send(int i,int x,int y) //这里面的参数 i,x , y 的含义分别是 模式0/1 , x坐标 ,  y坐标 , 可以根据需求改变{string str =Convert.ToString(i)+Convert.ToString(x) + Convert.ToString(y);//将数字转化为string类型字符串byte[] Btye = Encoding.UTF8.GetBytes(str);//将刚刚转化好的string类型字符串转化为byte类型数组ClientSocket.Send(Btye);//调用Socket类中的Send()函数发送数据if (str[0] == '0')//判断模式0/1,在己方控制台显示己方发送过去的内容,方便自己查看{Console.WriteLine($"已发送轰炸位置 {str}");}else if (str[0] == '1'){Console.WriteLine($"已发送对方轰炸位置结果{str}");}}

推荐阅读