Client-Server 在不同的机器和多个客户端上运行
Posted
技术标签:
【中文标题】Client-Server 在不同的机器和多个客户端上运行【英文标题】:Clien-Server to run on different machines and multiple clients 【发布时间】:2014-05-07 05:52:26 【问题描述】:我使用 C# 编写了一个客户端服务器程序,该程序在同一台机器上运行,客户端发送消息,服务器显示消息,我如何编辑我的程序以便服务器和客户端都在不同的机器上运行,还有10个客户端可以连接到服务器
这是我的客户代码:
public partial class ClientForm : Form
const int BUFFER_SIZE = 1024;
byte[] sendBuffer = new byte[BUFFER_SIZE];
byte[] rcvBuffer = new byte[BUFFER_SIZE];
Socket clientSocket;
const int PORT = 3333;
public ClientForm()
InitializeComponent();
void btnConnect_Click(object sender, EventArgs e)
try
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect to the local host
clientSocket.Connect(new IPEndPoint(IPAddress.Loopback, PORT));
catch (Exception ex) AppendToTextBox(ex.Message);
EnableSendButton();
void btnSend_Click(object sender, EventArgs e)
try
// Serialize the textBox text before sending
sendBuffer = Encoding.ASCII.GetBytes(textBoxInput.Text);
// Sends contents of textbox to the server
clientSocket.Send(sendBuffer);
// Prepares to receive something, i.e. the echo
clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);//.Receive(rcvBuffer);
catch (Exception ex) AppendToTextBox(ex.Message);
// About Asynchronous Callbacks: http://***.com/questions/1047662/what-is-asynccallback
void ReceiveCallback(IAsyncResult AR)
try
int bytesReceived = clientSocket.EndReceive(AR); // Number of bytes received
byte[] rcvBufferTrim = new byte[bytesReceived];
Array.Copy(rcvBuffer, rcvBufferTrim, bytesReceived); // Removes trailing nulls
string text = Encoding.ASCII.GetString(rcvBufferTrim); // Convert bytes into string
AppendToTextBox(DateTime.Now.ToString("HH:mm:ss") + ": " + text); // Displays buffer contents as text
// Starts receiving data again
clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);
catch (Exception ex) AppendToTextBox(ex.Message);
和服务器代码:
public partial class ServerForm : Form
const int BUFFER_SIZE = 1024;
byte[] rcvBuffer = new byte[BUFFER_SIZE]; // To recieve data from the client
Socket serverSocket;
Socket clientSocket; // We will only accept one client socket for now
const int PORT = 3333;
public ServerForm()
InitializeComponent();
StartServer();
void StartServer()
try
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(IPAddress.Any, PORT));
serverSocket.Listen(10); // Listen(1) means a maximum of one client pending
serverSocket.BeginAccept(AcceptCallback, null);
catch (Exception ex) AppendToTextBox(ex.Message);
// About Asynchronous Callbacks: http://***.com/questions/1047662/what-is-asynccallback
void AcceptCallback(IAsyncResult AR)
try
clientSocket = serverSocket.EndAccept(AR); // Client connected successfully, waiting for requests
AppendToTextBox("Client connected successfully...");
clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);
catch (Exception ex) AppendToTextBox(ex.Message);
void ReceiveCallback(IAsyncResult AR)
try
int bytesReceived = clientSocket.EndReceive(AR); // Number of bytes received
byte[] rcvBufferTrim = new byte[bytesReceived];
Array.Copy(rcvBuffer, rcvBufferTrim, bytesReceived); // Removes trailing nulls
string text = Encoding.ASCII.GetString(rcvBufferTrim); // Convert bytes into string
AppendToTextBox("Received Text: " + text);
if (text == "getdate")
text = "\t"+ System.DateTime.Now.ToString("dd.MM.yyyy");
else if (text == "gettime")
text = "\t"+ System.DateTime.Now.ToString("h:mm:ss ");
///////////////////////////////////////////////////////////////////////////////////
// Reply with echo
byte[] echoBuffer = Encoding.ASCII.GetBytes("Echo... " + text);
clientSocket.Send(echoBuffer);
// Starts receiving data again
clientSocket.BeginReceive(rcvBuffer, 0, rcvBuffer.Length, SocketFlags.None, ReceiveCallback, null);
catch (Exception ex) AppendToTextBox("Exception: " + ex.Message + "...");
// Provides a thread-safe way to append text to the textbox
void AppendToTextBox(string text)
MethodInvoker invoker = new MethodInvoker(delegate
textBox.Text += text + "\r\n\r\n";
textBox.SelectionStart = textBox.TextLength;
textBox.ScrollToCaret();
); // "\r\n" are for new lines
this.Invoke(invoker);
【问题讨论】:
试试这个:***.com/questions/19218589/… 或者这个:***.com/questions/7104293/… 【参考方案1】:要允许服务器和客户端位于两台不同的机器上,您需要更改 clientSocket.Connect(new IPEndPoint(IPAddress.Loopback, PORT));
到
IPAddress ipAd = IPAddress.Parse(YOUR IP HERE);
clientSocket.Connect(ipAd, YOUR PORT HERE);
如果您想查看它,我还在我的库中创建了一个简单的客户端:https://github.com/TheRealNOIG/TylerGregorcyksLibrary/blob/master/TylerGregorcyksLibrary/Main/SimpleClient.cs
现在制作一个可以处理多个客户端的服务器有点困难,但幸运的是我已经做了一个例子
class Server
private static int bufferSize = 2048;
private static byte[] buffer = new byte[bufferSize];
private static List<Socket> clientSockets = new List<Socket>();
private static Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
static void Main(string[] args)
Console.Title = "Server";
SetupServer();
Console.ReadKey();
CloseAllSockets();
private static void SetupServer()
Console.WriteLine("Settings Up Server Plz Wait");
serverSocket.Bind(new IPEndPoint(IPAddress.Any, YOUR PORT HERE));
serverSocket.Listen(10);
serverSocket.BeginAccept(new AsyncCallback(CallBack), null);
Console.WriteLine("Server Made");
private static void CallBack(IAsyncResult e)
try
Socket socket = serverSocket.EndAccept(e);
clientSockets.Add(socket);
Console.WriteLine("Client Connected");
socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), socket);
serverSocket.BeginAccept(new AsyncCallback(CallBack), null);
catch (Exception ex) Console.WriteLine(ex.Message);
private static void ReceiveCallBack(IAsyncResult e)
try
Socket socket = (Socket)e.AsyncState;
int received;
try
received = socket.EndReceive(e);
catch (SocketException)
Console.WriteLine("Client forcefully disconnected");
socket.Close();
clientSockets.Remove(socket);
return;
byte[] dataBuf = new byte[received];
Array.Copy(buffer, dataBuf, received);
string text = Encoding.ASCII.GetString(dataBuf);
Console.WriteLine("Client request: " + text);
string response = string.Empty;
try
if (command.ToLower() == "What Time is it")
response = DateTime.Now.ToString();
else if (command.ToLower() == "Whats your name")
response = "Tyler Gregorcyk";
else
response = "Invaled";
catch (Exception et) Console.WriteLine(et.Message); socket.Close(); clientSockets.Remove(socket);
if(response == string.Empty)
response = "Invaled";
if (response != string.Empty)
Console.WriteLine("Sent To Client: " + response);
byte[] data = Encoding.ASCII.GetBytes(response);
socket.Send(data);
serverSocket.BeginAccept(new AsyncCallback(CallBack), null);
conn.Close();
socket.BeginReceive(buffer, 0, bufferSize, SocketFlags.None, ReceiveCallBack, socket);
catch (Exception)
private static void CloseAllSockets()
foreach (Socket socket in clientSockets)
socket.Shutdown(SocketShutdown.Both);
socket.Close();
serverSocket.Close();
顺便说一句,这是 YouTube 上教程的编辑版本:https://www.youtube.com/watch?v=xgLRe7QV6QI
【讨论】:
以上是关于Client-Server 在不同的机器和多个客户端上运行的主要内容,如果未能解决你的问题,请参考以下文章
Errno 10061:无法建立连接,因为目标机器主动拒绝(客户端-服务器)
在 SFML 上检测到多个按键,无法以任何其他方式解决,并且在不同机器上的工作方式不同