我正在尝试使用以下代码构建一个简单的客户端 - 服务器应用程序:
//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 :(得分: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);
}
}
答案 1 :(得分:0)
如果您要编写服务器,一个好的设计是拥有[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!");
使用TcpListener和TcpClient,我认为使用Socket类进行网络编程要容易得多。我说这个的原因是它已经是一个非常好且易于使用的实现,并且通过使用TcpListener和TcpClient创建进一步的抽象,减少了你理解正在发生的事情的能力(在我看来)。