我有一个服务器应用程序和一个客户端应用程序。 我正在使用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
}
我的服务器代码是否有问题导致无法成为多客户端服务器系统?非常感谢帮助。提前谢谢。
答案 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服务来上传文件非常容易......
答案 2 :(得分:0)
试试这个
const int noOfClients = 5;
for(int i=0;i<noOfClients;i++)
{
Thread th = new Thread(new ThreadStart(ListenForPeers));
th.Start();
}