Обмен сообщениями через протокол Tcp - C#
Формулировка задачи:
Приветствую! Христос Воскресе!
Собственно, задание: Напишите программу, которая при запуске устанавливает TCP соединение с заданным сервером и открывает в пассивном режиме заданный порт TCP. После подключения к этому порту клиента, программа в цикле принимает данные от
клиента, передаёт их серверу, получает ответ сервера и возвращает его клиенту. После отключения клиента программа должна завершиться.
Код клиент:
Сервер:
В принципе, все реализовано. Но не получается пока реализовать этот момент: После отключения клиента программа должна завершиться.
И еще - как заставить сервер автоматически принять данные после их отправки от клиента.
PS: нельзя использовать стандартные классы типа TcpClient. Заранее предупреждаю, чтобы не постили лишнего.
public partial class Client : Form
{
string IP;
string Port;
Socket socket;
EndPoint end;
public Client(string ip, string port)
{
InitializeComponent();
this.IP = ip;
this.Port = port;
Control.CheckForIllegalCrossThreadCalls = false;
}
private void button1_Click(object sender, EventArgs e)
{
socket.Disconnect(true);
Application.Exit();
}
private void Client_Load(object sender, EventArgs e)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Parse(IP);
IPEndPoint ipe = new IPEndPoint(ip, int.Parse(Port));
end = (EndPoint)ipe;
try
{
socket.Connect(ipe);
this.Text += " - Соединение установлено";
}
catch
{
MessageBox.Show("Проблемы с установкой соединения.\nПриложение будет закрыто.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
Application.Exit();
}
}
private delegate void Answer();
private void button2_Click(object sender, EventArgs e)
{
string str = richTextBox1.Text;
byte[] buffer = Encoding.Default.GetBytes(str);
socket.Send(buffer, buffer.Length, 0);
new Answer(delegate() { Answ(); }).BeginInvoke(null, null);
}
private void Answ()
{
byte[] answer=new byte[64];
socket.ReceiveFrom(answer, 0, ref end);
textBox1.Text = Encoding.Default.GetString(answer);
}
}public partial class Server : Form
{
Socket socket;
Socket client;
IPEndPoint ipe;
byte[] buffer;
public Server()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress ip = IPAddress.Any;
ipe = new IPEndPoint(ip, 8080);
socket.Bind(ipe);
socket.Listen(100);
label1.Text = "Порт в режиме ожидания соединения";
new Connect(delegate() { Conect(); }).BeginInvoke(null, null);
}
private void Conect()
{
client = socket.Accept();
label1.Text = "Соединение установлено";
}
private delegate void Connect();
private void SendMessage()
{
buffer = new byte[256];
client.Receive(buffer, buffer.Length, 0);
richTextBox1.Text += Encoding.Default.GetString(buffer);
string str = "Сообщение получено";
byte[] service = Encoding.Default.GetBytes(str);
client.Send(service, service.Length, 0);
}
private void button1_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void button2_Click(object sender, EventArgs e)
{
SendMessage();
}
}Решение задачи: «Обмен сообщениями через протокол Tcp»
textual
Листинг программы
public partial class Server : Form
{
// делегат для ожидания соединения
private delegate void Connect();
// делегат для приема сообщений
private delegate void Send();
Socket socket;
Socket client;
EndPoint end;
byte[] buffer;
public Server()
{
InitializeComponent();
// чтобы не ругалось на то, что компоненты формы
// используются в другом потоке
Control.CheckForIllegalCrossThreadCalls = false;
}
private void Form1_Load(object sender, EventArgs e)
{
// инициализация сокета
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// говорим, чтобы сервер использовал любой ip
IPAddress ip = IPAddress.Any;
// созаем параметр для привязки сокета к адресу
IPEndPoint ipe = new IPEndPoint(ip, 8080);
end = (EndPoint)ipe;
// привязка сокета к адресу
socket.Bind(ipe);
// указываем количество запросов на соединение в очереди
socket.Listen(1);
label1.Text = "Порт в режиме ожидания соединения";
// выполняется асинхронно в потоке, тем самым программа не зависает
new Connect(delegate() { Conect(); }).BeginInvoke(null, null);
}
// подключение клиента к серверу
private void Conect()
{
client = socket.Accept();
label1.Text = "Соединение установлено";
}
// метод для получения сообщений и отправки ответа
private void SendMessage()
{
try
{
// получение сообщения
buffer = new byte[256];
client.ReceiveFrom(buffer, ref end);
Mess(buffer);
// отправка ответа
string str = "Сообщение получено";
byte[] service = Encoding.Default.GetBytes(str);
client.Send(service, service.Length, 0);
}
catch // если соединение разовано, то завешение приложения
{
Quit();
}
}
// кнопка выхода
private void button1_Click(object sender, EventArgs e)
{
Quit();
}
private void button2_Click(object sender, EventArgs e)
{
// ожидание сообщения не вызывает зависание программы
new Send(delegate() { Connected(); }).BeginInvoke(null, null);
}
// метод для запуска автоматического приема сообщений
private void Connected()
{
while (true)
{
SendMessage();
}
}
// обновление информации в текстовом окне
private void Mess(byte[] buf)
{
richTextBox1.Text += Encoding.Default.GetString(buf);
}
// метод для завершения приложения
private void Quit()
{
socket.Close();
Application.Exit();
}
}