TcpConnection способен обрабатывать параллельные запросы.Клиент-сервер - PullRequest
0 голосов
/ 21 мая 2011

Я пытаюсь создать простое клиент-серверное приложение со следующими кодами:

//SERVER
IPAddress ipAd = IPAddress.Parse("192.163.10.101");
TcpListener myList = new TcpListener(ipAd, 8001);
myList.Start();

Console.WriteLine("The server is running at port 8001...");
Console.WriteLine("The local End point is  :" + myList.LocalEndpoint);
Console.WriteLine("Waiting for a connection.....");

Socket s = myList.AcceptSocket();
Console.WriteLine("Connection accepted from " + s.RemoteEndPoint);

//CLIENT
TcpClient tcpclnt = new TcpClient();
Console.WriteLine("Connecting.....");
tcpclnt.Connect("192.163.10.101",8001); 
Console.WriteLine("Connected");

это действительно то, что мне нужно, когда клиент может подключиться к серверу. Однако, когда я пытаюсь запустить несколько экземпляров клиента для подключения к серверу, сервер принимает только первый клиент для подключения. Это означает, что существует соединение «один к одному», при котором только один клиент может подключиться к клиенту. Однако мне нужно дать серверу возможность принимать соединения от более чем одного клиента.

Если кто-нибудь подскажет мне возможное решение, я буду очень признателен! Спасибо!

Ответы [ 2 ]

1 голос
/ 21 мая 2011

Вам нужно снова вызвать AcceptSocket, чтобы принять другой сокет.
Типичным вариантом было бы вызвать BeginAcceptSocket и в обратном вызове EndAcceptSocket отправить клиентскую обработку в свой собственный поток (или рабочий поток, используя асинхронные методы).), а затем снова вызовите BeginAcceptSocket.

Этот фрагмент не проверен, но должен быть более или менее правильным / заставить вас думать в правильном направлении.

class Server
{
    public Server()
    {
        TcpListener listener = null;

        // init the listener

        listener.BeginAcceptSocket((ar) => AcceptLoop(ar, listener),null);
    }

    public void HandleClientSocketRead(IAsyncResult ar, byte[] recvBuffer, Socket clientSocket)
    {
        int recvd = clientSocket.EndReceive(ar);
        //do something with the data
        clientSocket.BeginReceive(recvBuffer, 0, 1024, SocketFlags.None, (ar2) => HandleClientSocketRead(ar2, recvBuffer, clientSocket), null);
    }

    public void AcceptLoop(IAsyncResult ar, TcpListener listener)
    {
        Socket clientSocket = listener.EndAcceptSocket(ar); // note that this can throw
        byte[] recvBuffer = new byte[1024];

        clientSocket.BeginReceive(recvBuffer, 0, 1024, SocketFlags.None, (ar2) => HandleClientSocketRead(ar2, recvBuffer, clientSocket), null);

        listener.BeginAcceptSocket((ar) => AcceptLoop(ar, listener), null);
    }
}
0 голосов
/ 21 мая 2011

Если вы хотите написать сервер, хорошим вариантом будет наличие [server] .exe и [client] .exe. [Server] .exe, конечно, будет принимать и обрабатывать все входящие соединения, поддерживать клиентские сокеты и выполнять любые необходимые действия. Ниже приведен очень базовый пример написания сервера для приема нескольких клиентских сокетов и сохранения их в объекте List. Это, однако, не многопоточное, поэтому код блокирует.

[сервер] .exe

//-----------------------------------------------------------------------------
// <copyright file="Program.cs" company="DCOM Productions">
//     Copyright (c) DCOM Productions.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------------

namespace MultiSocketServerExample {
    using System;
    using System.Net.Sockets;
    using System.Net;
    using System.Collections.Generic;

    class Program {

        static List<Socket> m_ConnectedClients = new List<Socket>();

        static void Main(string[] args) {
            Socket host = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            host.Bind(new IPEndPoint(IPAddress.Any, 9999));
            host.Listen(1);

            while (true) {
                m_ConnectedClients.Add(host.Accept());
                Console.WriteLine("A client connected.");
            }
        }
    }
}

Затем поработайте с вашими клиентами: (опять же очень базовый пример)

m_ConnectedClients[0].Send(Encoding.ASCII.GetBytes("hello!");

Сетевое программирование с классом Socket, на мой взгляд, намного проще, чем использование TcpListener и TcpClient. Причина, по которой я это говорю, заключается в том, что это уже действительно хорошая и простая в использовании реализация, и использование TcpListener и TcpClient, где они создают дополнительную абстракцию, уменьшает вашу способность понимать, что происходит (на мой взгляд).

...