程序连接到本地主机上的服务器,但没有';不能通过局域网或互联网工作

本文关键字:不能 工作 互联网 局域网 连接 主机 服务器 程序 | 更新日期: 2023-09-27 18:28:36

我用Windows窗体在普通C#上制作了一个超级简单的游戏,学习如何让程序在互联网上"对话"。服务器和客户端在同一个程序上,用户只需单击按钮即可选择自己是哪一个。

目前,只要服务器和客户端都在同一台电脑上运行,使用ip 127.0.0.1进行连接,它就可以正常工作。如果我尝试使用内部或外部ip(端口打开),它将不再工作("接受之前"触发,但"接收之前"不起作用)。

我从Darryl Braaten那里得到了我的代码基础,他回答了别人的问题:在多线程环境中创建c#异步套接字客户端

AsyncServer.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
namespace blockbattle
{
    public class AsyncServer
    {
        private const int port = 11000;
        public int clientID = -1;
        public string serverPos = "";
        public string clientPos = "";
        public string newBullets = "";
        public bool bulletsSent = false;
        public string receivedBullets = "";
        public void StartServer()
        {
            Thread thread = new Thread(Run) { IsBackground = true };
            thread.Start();
        }
        private void Run()
        {
            Debug.WriteLine("Running");
            TcpListener tcpListener = new TcpListener(IPAddress.Loopback, port);
            tcpListener.Start();
            while (true)
            {
                Debug.WriteLine("Before Accept");
                ServerState state = new ServerState { WorkSocket = tcpListener.AcceptSocket() };
                Debug.WriteLine("Before Receive");
                Receive(state);
            }
        }
        private void Receive(ServerState state)
        {
            state.WorkSocket.BeginReceive(state.Buffer, 0, ServerState.BufferSize, 0, ReceiveCallBack, state);
        }
        private void ReceiveCallBack(IAsyncResult ar)
        {
            ServerState state = (ServerState)ar.AsyncState;
            try
            {
                int byteReceived = state.WorkSocket.EndReceive(ar);
                if (byteReceived > 0)
                {
                    string receivedString = Encoding.UTF8.GetString(state.Buffer, 0, byteReceived);
                    string[] receivedData = receivedString.Split('+');
                    clientID = int.Parse(receivedData[0]);
                    clientPos = receivedData[1];
                    if (receivedData[2].Length > 0)
                        receivedBullets = receivedData[2];
                    byte[] bytesToSend = Encoding.UTF8.GetBytes(string.Format("{0}+{1}", serverPos, newBullets));
                    if (newBullets.Length > 0)
                    {
                        newBullets = "";
                        bulletsSent = true;
                    }
                    Array.Copy(bytesToSend, state.Buffer, bytesToSend.Length);
                    state.WorkSocket.Send(state.Buffer, 0, bytesToSend.Length, SocketFlags.None);
                    Array.Clear(state.Buffer, 0, state.Buffer.Length);
                    Receive(state);
                }
            }
            catch (Exception e)
            {
                Debug.Print(e.ToString());
            }
        }
        private class ServerState
        {
            public const int BufferSize = 1024;
            public readonly byte[] Buffer = new byte[BufferSize];
            public Socket WorkSocket = null;
        }
    }
}

AsyncClient.cs

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
namespace blockbattle
{
    public partial class AsyncClient
    {
        private const int port = 11000;
        private readonly int _clientId;
        private readonly Random _random;
        public string clientPos = "";
        public string serverPos = "";
        public string newBullets = "";
        public bool bulletsSent = false;
        public string receivedBullets = "";
        public string lastBullet = "";
        public AsyncClient(int clientId)
        {
            _clientId = clientId;
            _random = new Random(clientId);
        }
        public void StartClient(IPAddress serverIP)
        {
            try
            {
                Socket workSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ClientState state = new ClientState { WorkSocket = workSocket };
                workSocket.BeginConnect(new IPEndPoint(serverIP, port), ConnectCallBack, state);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }
        private void ConnectCallBack(IAsyncResult ar)
        {
            ClientState state = (ClientState)ar.AsyncState;
            state.WorkSocket.EndConnect(ar);
            Send(state);
        }
        private void Receive(ClientState clientState)
        {
            clientState.WorkSocket.BeginReceive(clientState.Buffer, 0, ClientState.BufferSize, 0, ReceiveCallBack, clientState);
        }
        private void ReceiveCallBack(IAsyncResult ar)
        {
            ClientState state = (ClientState)ar.AsyncState;
            Socket client = state.WorkSocket;
            int byteReceived = client.EndReceive(ar);
            if (byteReceived > 0)
            {
                string receivedString = Encoding.UTF8.GetString(state.Buffer, 0, byteReceived);
                string[] receivedData = receivedString.Split('+');
                serverPos = receivedData[0];
                if (receivedData[1].Length > 0)
                    receivedBullets = receivedData[1];
                Array.Clear(state.Buffer, 0, state.Buffer.Length);
                Thread.Sleep(33);
                Send(state);
            }
        }
        private void Send(ClientState clientState)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(string.Format("{0}+{1}+{2}", _clientId, clientPos, newBullets));
            if (newBullets.Length > 0)
            {
                newBullets = "";
                bulletsSent = true;
            }
            try
            {
                clientState.WorkSocket.BeginSend(buffer, 0, buffer.Length, 0, BeginSendCallBack, clientState);
            }
            catch (Exception ex)
            {
                Debug.Print(ex.Message);
            }
        }
        private void BeginSendCallBack(IAsyncResult ar)
        {
            ClientState state = (ClientState)ar.AsyncState;
            int byteSent = state.WorkSocket.EndSend(ar);
            Receive(state);
        }
    }
    public class ClientState
    {
        // Client socket.
        public Socket WorkSocket = null;
        // Size of receive buffer.
        public const int BufferSize = 1024;
        // Receive buffer.
        public byte[] Buffer = new byte[BufferSize];
        public int Count = 0;
    }
}

程序连接到本地主机上的服务器,但没有';不能通过局域网或互联网工作

TcpListener中将IPAddress.Loopback更改为IPAddress.Any