C#实践炸飞机socket通信( 二 )

3. 最后阐述一下 receive() 函数,再对方(服务器端)接收到你发送的信息之后,一定会返回一个信息(因为下棋是交互的嘛),这时候你便需要一个接收函数 receive() ,这个函数是用来接受对方发送的信息的,但是需要注意的是这个函数会随着你的进程一直运行,在from中是不需要调用的 。
public void Recive(){while (true)//因为是一直在另一个进程中运行,所以给一个死循环{byte[] Btye = new byte[1024];//接收也是byte数组的ClientSocket.Receive(Btye);receivestr = Encoding.UTF8.GetString(Btye,0,3);//转化为string类型if (receivestr[0] == '0')//判断模式0/1,在己方控制台显示对方发送过来的内容,方便查看对方信息{Console.WriteLine($"接受对方了轰炸位置{receivestr}");}else if(receivestr[0]=='1'){Console.WriteLine($"接受轰炸位置结果{receivestr}");}}}服务器类代码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 Server{public String receivestr = null;private Socket SocketWatch;private Socket SocketSend;private static Server server = null;private Server(string ip1, int port1){SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);Init(ip1,port1);}public static Server serversocket(string ip1, int port1){if (server == null){server = new Server(ip1, port1);}return server;}private void Init(string ip1, int port1){SocketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);IPEndPoint iPEnd = new IPEndPoint(IPAddress.Parse(ip1), port1);SocketWatch.Bind(iPEnd);SocketWatch.Listen(1);System.Windows.Forms.MessageBox.Show("开始监听...");Thread thread = new Thread(Listen);thread.IsBackground = true;thread.Start();}void Listen(){while (SocketSend==null){SocketSend = SocketWatch.Accept();}System.Windows.Forms.MessageBox.Show("连接成功..." + SocketSend.RemoteEndPoint.ToString());Thread reciveThread = new Thread(Recive);reciveThread.IsBackground = true;reciveThread.Start();}public void Recive(){while (true){byte[] buffer = new byte[1024];SocketSend.Receive(buffer);receivestr = Encoding.UTF8.GetString(buffer, 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[] buffer = Encoding.UTF8.GetBytes(str);SocketSend.Send(buffer);if (str[0] == '0'){Console.WriteLine($"已发送轰炸位置 {str}");}else if (str[0] == '1'){Console.WriteLine($"已发送对方轰炸位置结果{str}");}}}}2.具体分析:

  1. 对于 send() 和 receive() 函数就不过多赘述 , 主要分析一下 listen() 函数,listen() 函数其实是一个监听函数,只有监听成功之后才能够连接,才可以实例化一个发送Socket对象和一个接收Thread对象,而服务器端也是单例模式的,与客户端结构基本相同 。
四、对服务器类和客户类的具体使用1.代码部分(部分代码,不能直接使用,注释部分即内容)private void button2_Click(object sender, EventArgs e){if (Plane_Sum < 3){label4.Text = "请先放置坤坤";}else{if(ipok && portok){label4.Text = "坤坤已放置好";label3.Text = "你的回合";client = Client.clientsocket(ip,port); //实例化客户端serorcli = true;}else{label4.Text = "没有输入ip或者端口";}}}private void button1_Click(object sender, EventArgs e){if (Plane_Sum < 3){label4.Text = "请先放置坤坤";}else{if(ipok && portok){label4.Text = "坤坤已放置好";label3.Text = "对手回合";server = Server.serversocket(ip, port); //实例化服务器端serorcli = false;}else{label4.Text = "没有输入ip或者端口";}}}private void button3_Click(object sender, EventArgs e){if (Plane_Sum < 3){label4.Text = "请先放置坤坤";}else{if (serorcli == false&&ipok&&portok){while (server.receivestr == null) { }//判断有没有接收,直到有接收才可以跳出循环if (server.receivestr[0] == '0')//接收直接使用,由于接收是处于一直接收的状态{PutKunKun2(server.receivestr[1] - '0', server.receivestr[2] - '0');server.Send(1, Board1[server.receivestr[1] - '0', server.receivestr[2] - '0'], 0);//发送调用server.receivestr = null;//赋值为null,为下一次接收做准备}}}}private void textBox1_ipChanged(object sender, EventArgs e){ip = textBox1.Text; //输入ipipok = true;}private void textBox2_portChanged(object sender, EventArgs e){int.TryParse(textBox2.Text,out port); //输入portportok = true;}五、问题分析与总结1.问题分析:
  1. 在本项目中单例化对象中,对单例化思想并不清楚, 求助于舍友,在他的帮助下明白了,对象没有就创建,有的话就直接返回已经创建的对象 。

    推荐阅读