Пожалуйста помогите понять почему не работает мой консольный чат?!
Там я пока что по умолчанию все на локальном адресе построил, чтобы не вводить все время ip при отладке, короче собственно дело обстоит так: передается первое сообщение с клиента на сервер, сервер его получает (отображает), но не рассылает почему то остальным клиентам, а все последующие сообщения вообще игнорирует, в том числе и с других клиентов.
У меня единственное предположение что все эти асинхронные методы срабатывают только первый раз, из за этого коннектится только первый клиент, а остальные игнорятся.
сервер
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using static Helper;
namespace ChatServer
{
class Program
{
static void Main(string[] args)
{
try
{
var ip = GetLocalIPAddress();
//var ip = GetNetworkIPAddress();
var ep = new IPEndPoint(ip, 11000);
var listener = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listener.Bind(ep);
listener.Listen(10);
var acceptArgs = new SocketAsyncEventArgs();
acceptArgs.Completed += AcceptAsync_Completed;
acceptArgs.UserToken = new List<Socket>();
listener.AcceptAsync(acceptArgs);
Console.WriteLine($"Server was started with ip address: \"{ip}\".");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
static void AcceptAsync_Completed(object sender, SocketAsyncEventArgs e)
{
var ip = (e.AcceptSocket.RemoteEndPoint as IPEndPoint).Address;
Console.WriteLine($"Client with ip address: \"{ip}\" was connected.");
(e.UserToken as List<Socket>).Add(e.AcceptSocket);
var receiveArgs = new SocketAsyncEventArgs();
receiveArgs.Completed += ReceiveAsync_Completed;
receiveArgs.SetBuffer(new byte[BufferLength], 0, BufferLength);
receiveArgs.AcceptSocket = e.AcceptSocket;
receiveArgs.UserToken = e.UserToken;
e.AcceptSocket.ReceiveAsync(receiveArgs);
}
static void ReceiveAsync_Completed(object sender, SocketAsyncEventArgs e)
{
var ip = (e.AcceptSocket.RemoteEndPoint as IPEndPoint).Address;
var msg = Encoding.Unicode.GetString(e.Buffer);
msg = $"{ip}> {msg}";
Console.WriteLine(msg);
var data = Encoding.Unicode.GetBytes(msg);
(e.UserToken as List<Socket>).Where(s => s != e.AcceptSocket).ForEach(s => s.Send(data));
}
}
}
клиент
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.IO;
using static Helper;
namespace ChatClient
{
class Program
{
static void Main(string[] args)
{
try
{
var ip = GetLocalIPAddress();
//Console.Write("Server ip address: ");
//var ip = IPAddress.Parse(Console.ReadLine());
var ep = new IPEndPoint(ip, 11000);
var client = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
client.Connect(ep);
Console.WriteLine("The connection to the server is established.");
var receiveArgs = new SocketAsyncEventArgs();
receiveArgs.Completed += ReceiveAsync_Completed;
receiveArgs.SetBuffer(new byte[BufferLength], 0, BufferLength);
client.ReceiveAsync(receiveArgs);
while (true)
{
var oldColor = Console.ForegroundColor;
Console.ForegroundColor = ConsoleColor.Red;
Console.Write($"{ip}> ");
var msg = Console.ReadLine();
Console.ForegroundColor = oldColor;
var data = Encoding.Unicode.GetBytes(msg);
var sendArgs = new SocketAsyncEventArgs();
sendArgs.SetBuffer(data, 0, data.Length);
client.SendAsync(sendArgs);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Console.ReadKey();
}
static void ReceiveAsync_Completed(object sender, SocketAsyncEventArgs e)
{
var msg = Encoding.Unicode.GetString(e.Buffer);
Console.WriteLine(msg);
}
}
}
хэлпер
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Xml.Serialization;
using System.IO;
using System.Collections.Concurrent;
using System.Globalization;
using System.Text.RegularExpressions;
public static class Helper
{
public const int BufferLength = 1024;
public static IPAddress GetLocalIPAddress()
{
var hostName = Dns.GetHostName();
var ipHost = Dns.GetHostByName(hostName);
return ipHost.AddressList[0];
}
public static IPAddress GetNetworkIPAddress()
{
var htmlPage = new WebClient().DownloadString("https://2ip.ru");
var pattern = @"<big id=""d_clip_button"">(\d.+)</big>";
var match = Regex.Match(htmlPage, pattern);
return IPAddress.Parse(match.Groups[1].Value);
}
public static void ForEach<T>(this IEnumerable<T> seq, Action<T> action)
{
foreach (var item in seq)
action(item);
}
}