чат

 
0
 
.NET
Comments (3)
ava
AET | 17.01.2008, 15:58 #
нужна помащь создаю чат но оно завесает

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;
using System.Net.Sockets;

namespace WindowsApplication1
{
//Команды для взаимодействия между сервером и клиент
enum Command
{
Login, //Зарегистрируйте сервер
Logout, //Выходим из системы сервер
Message, //Пошлите текстовое сообщение всем клиентам
List, //Получите список пользователей в комнате беседы из сервера
Null //Без команды
}
public partial class Form6 : Form
{
public Socket clientSocket; //Основная розетка клиента
public string strName; //Имя, которым потребитель регистрируется в комнату

private byte[] byteData = new byte[1024];
public string DocName = "";
public Form6()
{
InitializeComponent();
}

private void button3_Click(object sender, EventArgs e)
{
this.Close();
}

private void btnSend_Click(object sender, EventArgs e)
{
try
{
//Заполните инфо для сообщения, чтобы посылать
Data msgToSend = new Data();

msgToSend.strName = strName;
msgToSend.strMessage = txtMessage.Text;
msgToSend.cmdCommand = Command.Message;

byte[] byteData = msgToSend.ToByte();

//Пошлите это в сервер
clientSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnSend), null);

txtMessage.Text = null;
}
catch (Exception)
{
MessageBox.Show("Не в состоянии послать сообщение в сервер.", "SGSclientTCP: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void OnSend(IAsyncResult ar)
{
try
{
clientSocket.EndSend(ar);
}
catch (ObjectDisposedException)
{ }
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSclientTCP: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void OnReceive(IAsyncResult ar)
{
try
{
clientSocket.EndReceive(ar);

Data msgReceived = new Data(byteData);
//Соответственно обработайте полученное сообщение
switch (msgReceived.cmdCommand)
{
case Command.Login:
lstChatters.Items.Add(msgReceived.strName);
break;

case Command.Logout:
lstChatters.Items.Remove(msgReceived.strName);
break;

case Command.Message:
break;

case Command.List:
lstChatters.Items.AddRange(msgReceived.strMessage.Split('*'));
lstChatters.Items.RemoveAt(lstChatters.Items.Count - 1);
txtChatBox.Text += "<<<" + strName + " has joined the room>>>\r\n";
break;
}

if (msgReceived.strMessage != null && msgReceived.cmdCommand != Command.List)
txtChatBox.Text += msgReceived.strMessage + "\r\n";

byteData = new byte[1024];

clientSocket.BeginReceive(byteData,
0,
byteData.Length,
SocketFlags.None,
new AsyncCallback(OnReceive),
null);

}
catch (ObjectDisposedException)
{ }
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSclientTCP: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void txtMessage_TextChanged(object sender, EventArgs e)
{
if (txtMessage.Text.Length == 0)
btnSend.Enabled = false;
else
btnSend.Enabled = true;
}

private void SGSClient_FormClosing(object sender, FormClosingEventArgs e)
{
if (MessageBox.Show("Are you sure you want to leave the chat room?", "SGSclient: " + strName,
MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No)
{
e.Cancel = true;
return;
}

try
{
//Пошлите сообщение в конец сеанса сервера
Data msgToSend = new Data();
msgToSend.cmdCommand = Command.Logout;
msgToSend.strName = strName;
msgToSend.strMessage = null;

byte[] b = msgToSend.ToByte();
clientSocket.Send(b, 0, b.Length, SocketFlags.None);
clientSocket.Close();
}
catch (ObjectDisposedException)
{ }
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSclientTCP: " + strName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void txtMessage_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
btnSend_Click(sender, null);
}
}

private void button2_Click(object sender, EventArgs e)
{
txtMessage.Text = "";
}

private void Form6_Load(object sender, EventArgs e)
{
this.Text = "SGSclientTCP: " + strName;

//Пользователь зарегистрировался в систему, так что мы теперь запрашиваем сервер, чтобы посылать
//имена всех потребителей, которые - в комнате беседы
Data msgToSend = new Data();
msgToSend.cmdCommand = Command.List;
msgToSend.strName = strName;
msgToSend.strMessage = null;

byteData = msgToSend.ToByte();

clientSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnSend), null);

byteData = new byte[1024];
//Начните слушать данные асинхронно
clientSocket.BeginReceive(byteData,
0,
byteData.Length,
SocketFlags.None,
new AsyncCallback(OnReceive),
null);
}
}
// Структура данных, которой сервер и клиент взаимодействует с
//друг другом
class Data
{
//Встроенный конструктор
public Data()
{
this.cmdCommand = Command.Null;
this.strMessage = null;
this.strName = null;
}

//Преобразовывает байты на объект Данных типа
public Data(byte[] data)
{
//Первые четыре байта - для Команды
this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);

//Следующие четыре магазина длина имени
int nameLen = BitConverter.ToInt32(data, 4);

//Следующие четыре магазина длина сообщения
int msgLen = BitConverter.ToInt32(data, 8);

//Этот чек убеждается, что strName пройден в массив байтов
if (nameLen > 0)
this.strName = Encoding.UTF8.GetString(data, 12, nameLen);
else
this.strName = null;

//Это проверяет на наличие недействительной области сообщения
if (msgLen > 0)
this.strMessage = Encoding.UTF8.GetString(data, 12 + nameLen, msgLen);
else
this.strMessage = null;
}

//Преобразовывает структуру Данных в массив байтов
public byte[] ToByte()
{
List<byte> result = new List<byte>();

//Первые четыре - для Команды
result.AddRange(BitConverter.GetBytes((int)cmdCommand));

//Добавьте длину имени
if (strName != null)
result.AddRange(BitConverter.GetBytes(strName.Length));
else
result.AddRange(BitConverter.GetBytes(0));

//Длина сообщения
if (strMessage != null)
result.AddRange(BitConverter.GetBytes(strMessage.Length));
else
result.AddRange(BitConverter.GetBytes(0));

//Добавьте имя
if (strName != null)
result.AddRange(Encoding.UTF8.GetBytes(strName));

//И, наконец мы добавляем текст сообщения к нашему массиву байтов
if (strMessage != null)
result.AddRange(Encoding.UTF8.GetBytes(strMessage));

return result.ToArray();
}

public string strName; //Имя, которым клиент регистрируется в комнату
public string strMessage; //Текст Сообщения
public Command cmdCommand; //Командный тип (вход, конец сеанса, посылает сообщение, и т.д. и т.п.)
}
}


added later:
верхни код клиента вот код сервера

using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;

namespace Server
{
//Команды для взаимодействия между сервером и клиент
enum Command
{
Login, //Зарегистрируйте сервер
Logout, //Выходите из системы сервер
Message, //Пошлите текстовое сообщение всем клиентам беседы
List, //Получите список пользователей в комнате беседы из сервера
Null //Без команды
}

public partial class SGSserverForm : Form
{
// Структура ClientInfo хранит необходимую информацию о каждом
//клиенте подключенном к серверу
struct ClientInfo
{
public Socket socket; //Розетка клиента
public string strName; //Имя, которым потребитель регистрировался в комнату беседы
}

// Сбор всех клиентов зарегистрированных в комнату ( массив типа ClientInfo)
ArrayList clientList;

// Основная розетка на которой сервер слушает клиентов
Socket serverSocket;

byte[] byteData = new byte[1024];

public SGSserverForm()
{
clientList = new ArrayList();
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
try
{
//Мы используем розетки TCP
serverSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);

//Правопреемник любое IP машина и слушать в номере порта 1000
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 1000);

//Свяжите и слушайте в данном адресе
serverSocket.Bind(ipEndPoint);
serverSocket.Listen(4);

//Примите поступающих клиентов
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSserverTCP",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void OnAccept(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);

//Начните слушать для больших клиентов
serverSocket.BeginAccept(new AsyncCallback(OnAccept), null);

//Как только клиент соединится, тогда начните получать команды из нее
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None,
new AsyncCallback(OnReceive), clientSocket);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSserverTCP",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

private void OnReceive(IAsyncResult ar)
{
try
{
Socket clientSocket = (Socket)ar.AsyncState;
clientSocket.EndReceive(ar);

//Превратите массив байтов полученных из пользователя в
//интеллектуальную форму объектных Данных
Data msgReceived = new Data(byteData);

//Мы пошлем этому объекту в ответе просьбу потребителей
Data msgToSend = new Data();

byte [] message;

//Если сообщение должно входить в систему, выходите из системы, или простое текстовое сообщение
//тогда когда посылаться в другой тип остатков сообщения тот же
msgToSend.cmdCommand = msgReceived.cmdCommand;
msgToSend.strName = msgReceived.strName;

switch (msgReceived.cmdCommand)
{
case Command.Login:

//When a user logs in to the server then we add her to our
//list of clients

ClientInfo clientInfo = new ClientInfo();
clientInfo.socket = clientSocket;
clientInfo.strName = msgReceived.strName;

clientList.Add(clientInfo);

//Set the text of the message that we will broadcast to all users
msgToSend.strMessage = "<<<" + msgReceived.strName + " has joined the room>>>";
break;

case Command.Logout:

//When a user wants to log out of the server then we search for her
//in the list of clients and close the corresponding connection

int nIndex = 0;
foreach (ClientInfo client in clientList)
{
if (client.socket == clientSocket)
{
clientList.RemoveAt(nIndex);
break;
}
++nIndex;
}

clientSocket.Close();

msgToSend.strMessage = "<<<" + msgReceived.strName + " has left the room>>>";
break;

case Command.Message:

//Set the text of the message that we will broadcast to all users
msgToSend.strMessage = msgReceived.strName + ": " + msgReceived.strMessage;
break;

case Command.List:

//Send the names of all users in the chat room to the new user
msgToSend.cmdCommand = Command.List;
msgToSend.strName = null;
msgToSend.strMessage = null;

//Collect the names of the user in the chat room
foreach (ClientInfo client in clientList)
{
//To keep things simple we use asterisk as the marker to separate the user names
msgToSend.strMessage += client.strName + "*";
}

message = msgToSend.ToByte();

//Send the name of the users in the chat room
clientSocket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientSocket);
break;
}

if (msgToSend.cmdCommand != Command.List) //List messages are not broadcasted
{
message = msgToSend.ToByte();

foreach (ClientInfo clientInfo in clientList)
{
if (clientInfo.socket != clientSocket ||
msgToSend.cmdCommand != Command.Login)
{
//Send the message to all users
clientInfo.socket.BeginSend(message, 0, message.Length, SocketFlags.None,
new AsyncCallback(OnSend), clientInfo.socket);
}
}

txtLog.Text += msgToSend.strMessage + "\r\n";
}

//If the user is logging out then we need not listen from her
if (msgReceived.cmdCommand != Command.Logout)
{
//Start listening to the message send by the user
clientSocket.BeginReceive(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(OnReceive), clientSocket);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSserverTCP", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

public void OnSend(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
client.EndSend(ar);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "SGSserverTCP", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}

//The data structure by which the server and the client interact with
//each other

ava
AET | 17.01.2008, 16:14 #
вот часть сервера

class Data
{
//Default constructor
public Data()
{
this.cmdCommand = Command.Null;
this.strMessage = null;
this.strName = null;
}

//Converts the bytes into an object of type Data
public Data(byte[] data)
{
//The first four bytes are for the Command
this.cmdCommand = (Command)BitConverter.ToInt32(data, 0);

//The next four store the length of the name
int nameLen = BitConverter.ToInt32(data, 4);

//The next four store the length of the message
int msgLen = BitConverter.ToInt32(data, 8);

//This check makes sure that strName has been passed in the array of bytes
if (nameLen > 0)
this.strName = Encoding.UTF8.GetString(data, 12, nameLen);
else
this.strName = null;

//This checks for a null message field
if (msgLen > 0)
this.strMessage = Encoding.UTF8.GetString(data, 12 + nameLen, msgLen);
else
this.strMessage = null;
}

//Converts the Data structure into an array of bytes
public byte[] ToByte()
{
List<byte> result = new List<byte>();

//First four are for the Command
result.AddRange(BitConverter.GetBytes((int)cmdCommand));

//Add the length of the name
if (strName != null)
result.AddRange(BitConverter.GetBytes(strName.Length));
else
result.AddRange(BitConverter.GetBytes(0));

//Length of the message
if (strMessage != null)
result.AddRange(BitConverter.GetBytes(strMessage.Length));
else
result.AddRange(BitConverter.GetBytes(0));

//Add the name
if (strName != null)
result.AddRange(Encoding.UTF8.GetBytes(strName));

//And, lastly we add the message text to our array of bytes
if (strMessage != null)
result.AddRange(Encoding.UTF8.GetBytes(strMessage));

return result.ToArray();
}

public string strName; //Name by which the client logs into the room
public string strMessage; //Message text
public Command cmdCommand; //Command type (login, logout, send message, etcetera)
}
}


сервер чувствует подключение клиента а вот прога клиента зависает вчем дело подскажите
ava
it_medved | 12.02.2008, 11:17 #
Ты думаешь, что людям очень нравится просматривать код более 500 строк текста??? Пройдись по коду пошаговой обработкой, и точно опиши, где зависает, что пишет студия.
Please register or login to write.
Firm of day
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Contributors
  AET   it_medved
Similar
advanced
Submit