程序连接到本地主机上的服务器,但没有';不能通过局域网或互联网工作
本文关键字:不能 工作 互联网 局域网 连接 主机 服务器 程序 | 更新日期: 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
。