2011-05-21 146 views
0

我试图建立与以下代码简单的客户端 - 服务器应用程序:能够处理并发请求的TcpConnection。客户端 - 服务器

//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"); 

这实际上做什么,我需要的,其中客户端可以连接到服务器。但是,当我尝试运行客户端的多个实例以连接服务器时,服务器仅接受第一个要连接的客户端。这意味着像一个一对一的连接,其中只有一个客户端可以连接到客户端。但是,我需要的是让服务器能够接受来自多个客户端的连接。

如果有人能指出我可能的解决方案,我真的很感激!谢谢!

+0

如果第一个客户端断开连接,您可以连接第二个客户端吗? – Oded 2011-05-21 05:54:29

+0

是的,我可以。我想实现的是让服务器接受多个连接的客户端。 :)感谢您的回应! – Smiley 2011-05-21 05:56:05

回答

1

您需要再次调用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

如果我使用此代码作为我的服务器,是否必须更改我的客户端的某些部分?我很抱歉,但我想我很困惑。谢谢您的帮助! :) – Smiley 2011-05-21 06:31:49

+0

没有。在服务器上执行异步操作和在客户端上执行同步操作是完全可以接受的。 – Yaur 2011-05-21 06:35:23

0

如果您正在寻找写一个服务器,一个好的设计是有一个[服务器] .exe和一个[客户] .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创建更多抽象,减少了理解正在发生的事情的能力(在我看来)。

+0

如果我打算为我的服务器使用这种类型的代码,那么我可能应该把我的代码放在while循环里吧?我的意思是因为我必须接受来自用户的一些输入并用服务器处理它。 – Smiley 2011-05-21 11:02:01

+0

想想你的应用程序需要做什么。您需要一个连接到服务器的客户端,可以接受多个命令(正在进行),并发送给服务器并由其处理。以该顺序。 1)写代码连接2)接受输入3)发送到服务器4)等待响应(这是客户端的命令),所以正确,你需要一个循环来接受输入。在输入准备好之后立即发送并等待响应,然后循环并重新开始 – 2011-05-21 20:41:24

相关问题