using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace client
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
public int port = 1116; //умолчание
public string adres = "192.168.100.21"; //умолчание
private TcpClient tcpServer;
private Thread thrMessaging;
private StreamWriter swSender;
private StreamReader srReceiver;
public delegate void dgUpdateLabel(string msg);
private void reg()
{
//создадим сокетное подключение для общения с сервером
tcpServer = new TcpClient(adres, port);
swSender = new StreamWriter(tcpServer.GetStream());
srReceiver = new StreamReader(tcpServer.GetStream()); //принятие
thrMessaging = new Thread(new ThreadStart(ReceiveMessages));
thrMessaging.Start();
//ну и тут ваше что-то*/
string resp = srReceiver.ReadLine();
label1.Text = resp;
}
public void SendMessage(string message) { // отправка сообщений
swSender.WriteLine(message);
swSender.Flush();
textBox1.Text = "";
}
public void ReceiveMessages() { // принятие сообщений от сервера
srReceiver = new StreamReader(tcpServer.GetStream()); //принятие
string Response = srReceiver.ReadLine();
while (true) {
if (Response != "") {
this.Invoke(new dgUpdateLabel(this.UpdateLog), new object[] { srReceiver.ReadLine() }); // обновляем текстбокс
Thread.Sleep(1000);
}
}
}
public void UpdateLog(string msg) {
textBox2.AppendText(msg+"\r\n");
}
void Button1Click(object sender, EventArgs e)
{
this.reg();
}
void Button2Click(object sender, EventArgs e)
{
this.SendMessage(textBox1.Text);
}
void MainFormFormClosed(object sender, FormClosedEventArgs e)
{
//swSender.Close();
//srReceiver.Close();
//tcpServer.Close();
}
private void button3_Click(object sender, EventArgs e)
{
//ReceiveMessages();
}
void TextBox1KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13) {
this.SendMessage(textBox1.Text);
}
}
void TextBox1TextChanged(object sender, EventArgs e)
{
// ...
}
}
}
C# мини Чат
Решил написать миниЧат, без навороченных функций. Хоть тема и заезженная, хоть и пересмотрел я кучу примеров - а хочет с нуля, да и свой. Приведу весь код, что бы было понятно в чем вопрос.
клиент .. WinForms
Код:
и сервер.. (консольное приложение)
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
namespace server
{
class Program
{
//для оздания отдельного процесса
public class Connection
{
public TcpClient cl;
StreamWriter swSender;
StreamReader srReceiver;
String str;
public void Work()
{
srReceiver = new StreamReader(cl.GetStream()); //принятие
swSender = new StreamWriter(cl.GetStream());
// сообщаем об успешном подключении
swSender.WriteLine("Connection Successfuly!");
swSender.Flush();
str = srReceiver.ReadLine();
while(true) { // цикл для принятия сообщений от клиента
Thread.Sleep(50);
Console.WriteLine(str); // выводим в консоль принятое сообщение
str = srReceiver.ReadLine();
//SendMsgToClient(str);
}
}
public void SendMsgToClient(string msg) {
swSender = new StreamWriter(cl.GetStream());
swSender.WriteLine(msg);
}
public void Sender() {
swSender = new StreamWriter(cl.GetStream());
//srReceiver = new StreamReader(cl.GetStream());
//string response;
//(response = srReceiver.ReadLine())
while (str != "") {
Thread.Sleep(50);
if (str != null) {
swSender.WriteLine(str);
swSender.Flush();
}
}
}
}
//многопроцессорная работа
static void Main(string[] args)
{
Console.WriteLine("Maka's (c) Server, the version 1.0.0.0 [borN_free]");
int port = 1116;
IPAddress localAdd = IPAddress.Parse("192.168.100.21");
TcpListener server = new TcpListener(localAdd, port);
server.Start(); //серер запущен
Console.WriteLine("The server is started... Waiting for connections..."); //уведомили об этом
while (true)
{
TcpClient cl = server.AcceptTcpClient();
Console.WriteLine("Connected!");
Connection c = new Connection();
c.cl = cl;
Thread t = new Thread(new ThreadStart(c.Work));
t.IsBackground = false;
t.Start();
// поток для отправки сообщений ОТ сервера
Thread sendThread = new Thread(new ThreadStart(c.Sender));
sendThread.IsBackground = false;
sendThread.Start();
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Net;
namespace server
{
class Program
{
//для оздания отдельного процесса
public class Connection
{
public TcpClient cl;
StreamWriter swSender;
StreamReader srReceiver;
String str;
public void Work()
{
srReceiver = new StreamReader(cl.GetStream()); //принятие
swSender = new StreamWriter(cl.GetStream());
// сообщаем об успешном подключении
swSender.WriteLine("Connection Successfuly!");
swSender.Flush();
str = srReceiver.ReadLine();
while(true) { // цикл для принятия сообщений от клиента
Thread.Sleep(50);
Console.WriteLine(str); // выводим в консоль принятое сообщение
str = srReceiver.ReadLine();
//SendMsgToClient(str);
}
}
public void SendMsgToClient(string msg) {
swSender = new StreamWriter(cl.GetStream());
swSender.WriteLine(msg);
}
public void Sender() {
swSender = new StreamWriter(cl.GetStream());
//srReceiver = new StreamReader(cl.GetStream());
//string response;
//(response = srReceiver.ReadLine())
while (str != "") {
Thread.Sleep(50);
if (str != null) {
swSender.WriteLine(str);
swSender.Flush();
}
}
}
}
//многопроцессорная работа
static void Main(string[] args)
{
Console.WriteLine("Maka's (c) Server, the version 1.0.0.0 [borN_free]");
int port = 1116;
IPAddress localAdd = IPAddress.Parse("192.168.100.21");
TcpListener server = new TcpListener(localAdd, port);
server.Start(); //серер запущен
Console.WriteLine("The server is started... Waiting for connections..."); //уведомили об этом
while (true)
{
TcpClient cl = server.AcceptTcpClient();
Console.WriteLine("Connected!");
Connection c = new Connection();
c.cl = cl;
Thread t = new Thread(new ThreadStart(c.Work));
t.IsBackground = false;
t.Start();
// поток для отправки сообщений ОТ сервера
Thread sendThread = new Thread(new ThreadStart(c.Sender));
sendThread.IsBackground = false;
sendThread.Start();
}
}
}
}
Ребята, главный мой вопрос и непонимание находится в сервере.. Я из клиента отправляю сообщение серверу, сервер должен принять его, и (в дальнейшем) разослать всем клиентам. в данном случае - отослать принятое сообщение обратно клиенту. Так вот и не понимаю я, правильно ли я использую потоки, в какой из функций я должен принимать/отправлять от сервера обратно сообщение, в Work или в Sender??
прошу дать совет, очень хочется разобраться.
Спасибо.
Не всматривался в код но как я думаю если он сам рассылает всем пользователям сообщения.. то это большая нагрузка чем если бы клиенты сами забирали с сервера сообщения.
изменил код в сервере на такой
Код:
public void Work()
{
srReceiver = new StreamReader(cl.GetStream()); //принятие
swSender = new StreamWriter(cl.GetStream());
// сообщаем об успешном подключении
swSender.WriteLine("Connection Successfuly!");
swSender.Flush();
str = "";
//str = srReceiver.ReadLine();
//clientQueue.Enqueue(str);
while((str = srReceiver.ReadLine()) != "") { // цикл для принятия сообщений от клиента
clientQueue.Enqueue(str);
Thread.Sleep(50);
Console.WriteLine(str); // выводим в консоль принятое сообщение
}
}
public void Sender() {
TcpClient[] tcpClients = new TcpClient[htUsers.Count]; // содержит массив клиентов
string[] namesClients = new string[htUsers.Count]; // массив ников клиентов
htUsers.Values.CopyTo(tcpClients, 0);
htUsers.Keys.CopyTo(namesClients, 0);
int k = 0, p=0;
string msg;
while (true) {
Thread.Sleep(5000);
while (clientQueue.Count > 0) {
msg = (string)clientQueue.Dequeue();
k = 0;
for (k= 0; k< tcpClients.Length; k++) {
StreamWriter swSender = new StreamWriter(tcpClients[k].GetStream());
swSender.WriteLine(msg);
swSender.Flush();
}
}
}
}
}
{
srReceiver = new StreamReader(cl.GetStream()); //принятие
swSender = new StreamWriter(cl.GetStream());
// сообщаем об успешном подключении
swSender.WriteLine("Connection Successfuly!");
swSender.Flush();
str = "";
//str = srReceiver.ReadLine();
//clientQueue.Enqueue(str);
while((str = srReceiver.ReadLine()) != "") { // цикл для принятия сообщений от клиента
clientQueue.Enqueue(str);
Thread.Sleep(50);
Console.WriteLine(str); // выводим в консоль принятое сообщение
}
}
public void Sender() {
TcpClient[] tcpClients = new TcpClient[htUsers.Count]; // содержит массив клиентов
string[] namesClients = new string[htUsers.Count]; // массив ников клиентов
htUsers.Values.CopyTo(tcpClients, 0);
htUsers.Keys.CopyTo(namesClients, 0);
int k = 0, p=0;
string msg;
while (true) {
Thread.Sleep(5000);
while (clientQueue.Count > 0) {
msg = (string)clientQueue.Dequeue();
k = 0;
for (k= 0; k< tcpClients.Length; k++) {
StreamWriter swSender = new StreamWriter(tcpClients[k].GetStream());
swSender.WriteLine(msg);
swSender.Flush();
}
}
}
}
}
теперь из одного клиента НЕ ВСЕГДА, а точнее редко доходят сообщения до другого, и наоборот. В чем может быть проблема? ведь в цикле отправляются сообщения каждому. Может ли быть здесь конфликт потоков с разделяемым ресурсов очередью?
Спасибо