C#套接字服务器仅在本地进行通信

时间:2016-08-23 03:36:23

标签: c# visual-studio sockets

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

示例:

如果Endpoint Server是:(192.168.0.1,32000)
    端点客户端是:(192.168.0.1,32000)
    他们联系并共同发展。

但是

如果Endpoint Server是:(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);
    }
}

我需要服务器类型&#34;时钟&#34;这将发送给所有客户。

因此,客户收到,客户发送给服务器各自的时间。

1 个答案:

答案 0 :(得分:0)

只需使用以下

替换您的客户端启动功能
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
        {

        }
    }