【问题标题】:C# Socket Server communicates only locallyC# Socket Server 仅在本地通信
【发布时间】:2016-08-23 12:18:21
【问题描述】:

我需要创建一个应用程序来返回所有连接到套接字服务器的客户的小时数。 但我的应用程序只能在本地通信。

例子:

如果端点服务器是:(192.168.0.1, 32000)
端点客户端是:(192.168.0.1, 32000)
他们相互联系和交流。

但是

如果端点服务器是:(192.168.0.1, 32000)
端点客户端是:(192.168.0.2, 32000)
他们连接,但不交流。

服务器代码:

class Server:Sincronia
{
    GetIP getip = new GetIP();

    private Socket _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    private List<Socket> ListaDeClientesSockets = new List<Socket>();   /*Lista de sockets para adicionar clientes*/

    private List<string> ListaDeClients = new List<string>();

    private List<string> ListaDeHoras = new List<string>();

    private const int _BUFFER_SIZE = 2048;
    private int _PORT;
    private string Ip;
    private byte[] _buffer = new byte[_BUFFER_SIZE];

    public Server(string IP, int port)  /*Construtor para inicialização do IP e da Porta*/
    {
        this.Ip = IP;
        this._PORT = port;
    }

    public  void Connect()
    {
        Console.WriteLine("Socket Server ON");
        Console.WriteLine(getip.getIP());
        _serverSocket.Bind(new IPEndPoint(IPAddress.Parse(getip.getIP()), _PORT));
        _serverSocket.Listen(5);
        _serverSocket.BeginAccept(AcceptCallback, null);
    }


    public void ShowAllClients()
    {
        Console.WriteLine("####################### " + ListaDeClientesSockets.Count + " #######################");


        for (int i = 0; i < ListaDeClientesSockets.Count; i++)
        {
            int j = i + 1;
            Console.WriteLine("Client : " + j + " IP : " + ListaDeClients[i]);
        }
    }

    private  void CloseConnections()
    {

        foreach (Socket socket in ListaDeClientesSockets)
        {
            socket.Shutdown(SocketShutdown.Both);
            socket.Close();
        }

        _serverSocket.Close();
    }

    /// <summary>AcceptCallback método da classe Server
    /// Evento realizado para aceitar conexões dos clientes adicionando em uma lista genérica
    /// /// </summary>

    private void AcceptCallback(IAsyncResult asyncronousResult)
    {
        Socket socket;

        try
        {
            socket = _serverSocket.EndAccept(asyncronousResult);
        }
        catch (ObjectDisposedException)
        {
            return;
        }

        ListaDeClientesSockets.Add(socket);
        ListaDeClients.Add(((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
        socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
        Console.WriteLine("Client Connect " + ((IPEndPoint)socket.RemoteEndPoint).Address.ToString());
        _serverSocket.BeginAccept(AcceptCallback, null);
    }


    public void SendToALL(string text)
    {
        foreach(Socket socket in ListaDeClientesSockets.ToList())
        {
            ListaDeHoras.Clear();
            byte[] dataByte = Encoding.ASCII.GetBytes(text);

            socket.Send(dataByte);

        }
    }
    /// <summary>ReceiveCallBack método da classe Server
    /// Evento realizado para receber e enviar dados do cliente através de um IASyncResult
    /// </summary>

    private  void ReceiveCallback(IAsyncResult asyncronousResult)   
    {
        Socket current = (Socket)asyncronousResult.AsyncState;
        int received;

        try
        {
            received = current.EndReceive(asyncronousResult);
        }
        catch (SocketException) /*Catch realizado caso houver perca de conexão com o cliente*/
        {
            Console.WriteLine("Conexão com o cliente " + ((IPEndPoint) current.RemoteEndPoint).Address.ToString() + " perdida.");
            current.Close();
            ListaDeClients.Remove(((IPEndPoint)current.RemoteEndPoint).Address.ToString());
            ListaDeClientesSockets.Remove(current);
            return;
        }

        byte[] recBuf = new byte[received];
        Array.Copy(_buffer, recBuf, received);
        string text = Encoding.ASCII.GetString(recBuf);

        Console.WriteLine("Received Text: " + text);
        ListaDeHoras.Add(text);


        current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);

    }
}

程序服务器代码:

   class Program
{
    static void Main(string[] args)
    {
        Console.Title = "Servidor";

        Server server = new Server("localhost", 8000);

        server.Connect();
        while (true)
        {
            string text = Console.ReadLine();

            if (text == "mostrar")
                server.ShowAllClients();
            else
                server.SendToALL(text);
        }

        Console.ReadKey();
    }
}

客户代码:

   class Client
{
    Socket socketClient;

    static int port = 8000;
    static string localhostIP = "127.0.0.1";

    private const int _BUFFER_SIZE = 2048;
    private byte[] _buffer = new byte[_BUFFER_SIZE];

    private string IP;

    public Client(string ip)
    {
        this.IP = ip;
    }

    public void Start()
    {
        IPEndPoint endp = new IPEndPoint(IPAddress.Parse(IP), port);
        try
        {
            socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketClient.BeginConnect(endp, new AsyncCallback(ConnectCALLBACK), socketClient);
            Receive(socketClient);
        }
        catch
        {

        }
    }

    private void ConnectCALLBACK(IAsyncResult assynresult)
    {
        try
        {
            Socket client = (Socket)assynresult.AsyncState;
            Console.WriteLine("Conectado");
            client.EndConnect(assynresult);
        }
        catch(SocketException)
        {
            Console.WriteLine("Falta de conexão com o servidor, verifique sua conexão.");
        }

    }

    public void Receive(Socket socket)
    {
        try
        {
            socket.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, socket);
        }
        catch
        {

        }
    }

    private void ReceiveCallback(IAsyncResult asyncronousResult)
    {
        Socket current = (Socket)asyncronousResult.AsyncState;
        int received;

        try
        {
            received = current.EndReceive(asyncronousResult);
        }
        catch (SocketException)
        {
            return;
        }

        byte[] recBuf = new byte[received];
        Array.Copy(_buffer, recBuf, received);
        string text = Encoding.ASCII.GetString(recBuf);

        if(text == "clock")
        {
            string horas = DateTime.Now.ToString("dd-MM-yyyy HH:mm");
            byte[] sended = Encoding.ASCII.GetBytes(horas);
            current.Send(sended);
        }


        current.BeginReceive(_buffer, 0, _BUFFER_SIZE, SocketFlags.None, ReceiveCallback, current);
    }
}

我需要服务器类型“时钟”,它会发送给所有客户端。

为了让客户端接收,客户端将它们各自的时间发送到服务器。

【问题讨论】:

  • 您是否测试过服务器中的端口是否位于防火墙后面或仅对所有网络开放,看起来您用于通信的端口位于防火墙后面
  • Ja 被释放了门,但它不起作用。
  • 假设您已正确配置服务器和客户端的 IP 地址,则您的网络配置存在问题。如果没有,则说明您的代码中有印刷错误。无论哪种方式,这个问题都是题外话。如果您认为这不是这两种可能性之一,请修正您的问题,以便它包含一个良好的 minimal reproducible example 以可靠地重现问题。
  • 嗯..我正在尝试测试,但总是一样,我只得到本地

标签: c# visual-studio sockets


【解决方案1】:

只需将您的客户端启动功能替换为以下内容

public void Start()
    {
        IPEndPoint endp = new IPEndPoint(IPAddress.Parse(IP), port);
        try
        {
            socketClient = new Socket(endp, SocketType.Stream, ProtocolType.Tcp);
            socketClient.BeginConnect(endp, new AsyncCallback(ConnectCALLBACK), socketClient);
            Receive(socketClient);
        }
        catch
        {

        }
    }

【讨论】:

  • 在 socketClient = new Socket(end,...) 上,endp 无法从“System.Net.IPEndpoint”转换为“System.Sockets.AddressFamily”
猜你喜欢
  • 2014-05-28
  • 2016-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2011-09-25
相关资源
最近更新 更多