потоки и сокеты
Мне в одном проекте нужно реализовать общение между двумя программами через интернет. Много не нужно - буквально по одной строчке передавать. Нашел пример консольных tcp-сервера и клиента на System::Net::Sockets, попытался сделать по аналогии в формах(С++), получил зависание на методах ReadLine/Read, AcceptTcpClient. Пустил их по отдельным потокам(а правильно ли?) - зависание пропало, но и до конца всё не заработало. Так вот, прошу объяснить как решить такую задачу. Буду крайне признателен простенькому примеру в формах.
Общий ход решения абсолютно правильный, вам необходима многопоточность. Что конкретно не работает?
Сервер вроде как создаётся и ждёт подключения. Клиент вроде как видит сервер, ибо не падает. Но AcceptTcpClient, насколько я понял не проходит. Всё сделано очень криво. Мне бы наводочку на путь истинный. Общий ход решения понятен, но я не особо разобрался с System::Net::Sockets.
Код:
public delegate void WriteTextHandler(System::String^ text);
//блаблабла
void WriteText(System::String^ text)
{
label1->Text = text;
}
void Read(System::Object^ o_client)
{
TcpClient^ client = (TcpClient^)o_client;
StreamReader^ reader = gcnew StreamReader(client->GetStream());
this->Invoke(gcnew WriteTextHandler(this, &Form1::WriteText), reader->ReadLine());
label1->Text = reader->ReadLine();
client->Close();
}
void Listen()
{
TcpListener^ server = gcnew TcpListener(3333);
server->Start();
while (true)
{
TcpClient^ client = server->AcceptTcpClient();
Thread^ th = gcnew Thread(gcnew ParameterizedThreadStart(this, &Form1::Read));
th->Start(client);
}
}
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Thread^ th = gcnew Thread(gcnew ThreadStart(this, &Form1::Listen));
th->Start();
button1->Enabled = false;
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
TcpClient^ client = gcnew TcpClient();
client->Connect("localhost", 3333);
if (client->Connected)
{
StreamWriter^ wr = gcnew StreamWriter(client->GetStream());
wr->WriteLine(textBox1->Text);
}
client->Close();
}
//блаблабла
void WriteText(System::String^ text)
{
label1->Text = text;
}
void Read(System::Object^ o_client)
{
TcpClient^ client = (TcpClient^)o_client;
StreamReader^ reader = gcnew StreamReader(client->GetStream());
this->Invoke(gcnew WriteTextHandler(this, &Form1::WriteText), reader->ReadLine());
label1->Text = reader->ReadLine();
client->Close();
}
void Listen()
{
TcpListener^ server = gcnew TcpListener(3333);
server->Start();
while (true)
{
TcpClient^ client = server->AcceptTcpClient();
Thread^ th = gcnew Thread(gcnew ParameterizedThreadStart(this, &Form1::Read));
th->Start(client);
}
}
#pragma endregion
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
Thread^ th = gcnew Thread(gcnew ThreadStart(this, &Form1::Listen));
th->Start();
button1->Enabled = false;
}
private: System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) {
TcpClient^ client = gcnew TcpClient();
client->Connect("localhost", 3333);
if (client->Connected)
{
StreamWriter^ wr = gcnew StreamWriter(client->GetStream());
wr->WriteLine(textBox1->Text);
}
client->Close();
}