サーバーとクライアントの 2 つの部分で構成されるチャット プログラムをコーディングしてきました。サーバーはTcpListener
、サーバーに参加するための着信要求をリッスンするために使用し、クライアントはTcpClient
それを使用してサーバーに接続し、メッセージを送信します。これまでのところ、クライアントが接続したときに送信される最初のメッセージであるハンドシェイクがあります。これには、クライアントの IP アドレスとニックネーム セットが含まれています。サーバーが非同期でリッスンするようにする方法がわかりません。非同期でない場合、チャットはclient -> server -> client -> server
一度に複数のクライアントに接続し、一度に複数のメッセージを受信する必要があるためです。これまでの私のコードは同期的に書かれています:
クライアント:
public void StartClient(string serverIP)
{
ReadWrite rw = new ReadWrite();
string nick = rw.GetNick();
string handshakeContents = "HANDSHAKE:" + nick + ":" + GetIP();
Int32 serverPort = 1336; // yay
TcpClient client = new TcpClient(serverIP, serverPort);
Console.WriteLine("Sending initial handshake: {0}", handshakeContents);
Byte[] data = System.Text.Encoding.ASCII.GetBytes(handshakeContents); // Convert handshakeContents to Byte[]
NetworkStream stream = client.GetStream(); // Instantiate object "stream" for use in read/write
stream.Write(data, 0, data.Length); // Send handshakeContents in Byte[] to server
Console.WriteLine(" - Connecting to IlanChat Server on ip {0}", serverIP);
Thread.Sleep(1000); // sleep 1s
data = new Byte[256];
string responseHandshake = String.Empty; // response handshake from server
Int32 bytes = stream.Read(data, 0, data.Length); // Read handshake.
responseHandshake = System.Text.Encoding.ASCII.GetString(data, 0, bytes); // Decode from Byte[] to ASCII string
Console.WriteLine(" - Received response handshake: {0}", responseHandshake);
Console.WriteLine(" - Successfully connected to IlanChat server on IP {0}", serverIP); // display message
Thread.Sleep(2000);
Console.Clear();
List<string> messagesRecieved = new List<string>();
while(true)
{
Console.Clear();
foreach (string msg in messagesRecieved)
{
Console.WriteLine(msg);
}
Console.WriteLine();
Console.Write("Enter message: ");
string msgRaw = Console.ReadLine();
string sendMsg = nick + ": " + msgRaw;
data = new Byte[256];
data = System.Text.Encoding.ASCII.GetBytes(sendMsg);
stream.Write(data, 0, data.Length); // finish this async shit
}
}
サーバ:
List<string> clientIP = new List<string>();
List<string> clientNicks = new List<string>();
string responseHandshake = "hello";
Int32 serverPort = 1336;
IPAddress machineIP = IPAddress.Parse(GetIP());
Console.Clear();
Console.WriteLine(" - Starting IlanChat server on IP {0}", machineIP);
TcpListener server = null;
server = new TcpListener(machineIP, serverPort);
server.Start();
Byte[] buffer = new Byte[256];
String data = null;
Console.WriteLine("Successfully started IlanChat server!");
while (true) // first alpha - only one user at a time
{
Console.WriteLine();
Console.WriteLine("Waiting for connections..");
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("User connecting..");
Console.WriteLine("Receiving handshake data..");
data = null;
NetworkStream stream = client.GetStream();
int i;
while ((i = stream.Read(buffer, 0, buffer.Length)) != 0)
{
data = System.Text.Encoding.ASCII.GetString(buffer, 0, i);
Console.WriteLine("Received handshake data: {0}", data);
Console.WriteLine("Processing data.."); // sample handshake: - HANDSHAKE:nick:ip
string tempNick = data.Replace("HANDSHAKE:", "");
string[] userDetails = tempNick.Split(':'); // should store to 0:nick, 1:ip
Console.WriteLine("Received client nick: {0}", userDetails[0]);
Console.WriteLine("Received client IP: {0}", userDetails[1]);
break;
}
Thread.Sleep(1100); // sleep
buffer = System.Text.Encoding.ASCII.GetBytes(responseHandshake);
Console.WriteLine("Sending response handshake..");
stream.Write(buffer, 0, buffer.Length);
}
サーバーが一度に複数の接続を受け入れ、それらを維持する方法はありますか? また、クライアントに一度に複数のメッセージを受信させ、メッセージを更新しながら入力させる方法はありますか?