多客户端服务器应用程序的C#问题

时间:2011-01-03 20:56:09

标签: c# multithreading client-server data-transfer

我有一个服务器应用程序和一个客户端应用程序。 我正在使用socket在服务器和客户端之间进行通信。如果只有一个客户端连接,一切正常:上传,下载所有工作都很好。

但如果有另一个客户端连接(我再次启动客户端应用程序,这意味着我的计算机上运行了2个客户端应用程序和1个服务器应用程序),我的服务器开始陷入困境:服务器无法接收文件上传客户端,客户端无法从服务器下载。

在服务器代码中,我已经为每个客户端连接使用了多线程,所以我无法弄清楚问题。这是我的服务器代码:

    private void ServerForm_Load(object sender, System.EventArgs e)
            {

                //...
                Thread th = new Thread(new ThreadStart(ListenForPeers));
                th.Start();
            }

    public void ListenForPeers()
            {
                    serversocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    serversocket.Blocking = true;
                    IPHostEntry IPHost = Dns.GetHostEntry(server);
                    string[] aliases = IPHost.Aliases;
                    IPAddress[] addr = IPHost.AddressList;
                    IPEndPoint ipepServer = new IPEndPoint(addr[0], 8090);
                    serversocket.Bind(ipepServer);
                    serversocket.Listen(-1);
                    while (true)
                    {
                        clientsock = serversocket.Accept();
                        if (clientsock.Connected)
                        {
                            total_clients_connected++;
                            AppendText("Client connected...");
                            Thread tc = new Thread(new ThreadStart(listenclient));
                            tc.Start();
                        }
             }


    void listenclient()
        {
             // start communication
        }

我的服务器代码是否有问题导致无法成为多客户端服务器系统?非常感谢帮助。提前谢谢。

3 个答案:

答案 0 :(得分:4)

看起来您已将clientSocket定义为所有服务器线程都使用的全局变量,而您希望它是每个线程的本地引用。您可以使用ParameterizedThreadStart执行此操作:

public void listenForPeers()
{
  //Setup the server socket

  while(true){
    Socket newClient = serverSock.Accept();
    if(newClient.Connected){
      Thread tc = new Thread(new ParameterizedThreadStart(listenclient));
      tc.start(newClient);
    }
  }
}

void listenclient(object clientSockObj)
{
  Socket clientSock = (Socket)clientSockObj;

  //communication to client via clientSock.
}

答案 1 :(得分:1)

首先,您将套接字的Blocking属性设置为true。这将阻止任何请求,直到之前的请求结束...

见这里:http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.blocking(VS.80).aspx

  

如果你处于阻止模式,那么你   做一个没有的方法调用   立即完成您的申请   将阻止执行直到   请求的操作完成。如果你   希望执行继续,即使   请求的操作不是   完成后,更改阻止属性   为假。阻止属性没有   对异步方法的影响。如果你   正在发送和接收数据   异步并想阻止   执行,使用ManualResetEvent   类。

您可能想重新考虑这样做,而是使用WCF或Web服务上传文件......它会更容易,IIS将为您处理线程。编写Web服务来上传文件非常容易......

http://www.c-sharpcorner.com/UploadFile/scottlysle/UploadwithCSharpWS05032007121259PM/UploadwithCSharpWS.aspx

答案 2 :(得分:0)

试试这个

const int noOfClients = 5;

for(int i=0;i<noOfClients;i++)
{
  Thread th = new Thread(new ThreadStart(ListenForPeers));
  th.Start();
}