Я новичок в программировании, поэтому, если в моем коде есть какая-то нелепая ошибка или плохие идеи, дайте мне знать. :)
Я создал пустой проект CLR в Visual Studio, чтобы попытаться добавить графический интерфейс к клиенту программы обмена сообщениями, которую я написал на c ++.
Клиент интерфейса работает нормально, но этомогу только отправлять сообщения, потому что я не мог найти способ перевести способ, которым я закодировал в клиенте консоли к интерфейсу. В консольном клиенте я использовал библиотеку <future>
для создания асинхронного потока, чтобы он мог продолжать проверять наличие новых сообщений от сервера.
Примерно так:
future<void> f1 = async(launch::async, newMsg, sock);
void newMsg(SOCKET sock)
{
while (true)
{
char buffer[512];
ZeroMemory(buffer, 512);
int byteRecived = recv(sock, buffer, 512, 0);
if (byteRecived > 0)
{
cout << string(buffer, 0, byteRecived) << endl;
}
}
}
Но при компиляции с clr <future>
не поддерживается. Можно ли как-нибудь заставить программу всегда проверять наличие сообщений, а также отправлять сообщения?
Я использую winsock tcp / ip для подключения клиент-сервер.
JanelaPrincipal.h
#include <Windows.h>
#include "iostream"
#include "winsock2.h"
#include "WS2tcpip.h"
#include "string"
#include "locale.h"
#include <msclr\marshal_cppstd.h>
#pragma comment(lib, "ws2_32.lib")
#pragma once
namespace FakeWpp {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for JanelaPrincipal
/// </summary>
public ref class JanelaPrincipal : public System::Windows::Forms::Form
{
public:
SOCKET sock;
JanelaPrincipal(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~JanelaPrincipal()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ buttonEnviar;
protected:
private: System::Windows::Forms::TextBox^ textBoxEnviar;
private: System::Windows::Forms::TextBox^ textBoxReceber;
private: System::Windows::Forms::Button^ buttonConectar;
protected:
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->buttonEnviar = (gcnew System::Windows::Forms::Button());
this->textBoxEnviar = (gcnew System::Windows::Forms::TextBox());
this->textBoxReceber = (gcnew System::Windows::Forms::TextBox());
this->buttonConectar = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// buttonEnviar
//
this->buttonEnviar->Location = System::Drawing::Point(197, 226);
this->buttonEnviar->Name = L"buttonEnviar";
this->buttonEnviar->Size = System::Drawing::Size(75, 23);
this->buttonEnviar->TabIndex = 0;
this->buttonEnviar->Text = L"Enviar";
this->buttonEnviar->UseVisualStyleBackColor = true;
this->buttonEnviar->Click += gcnew System::EventHandler(this, &JanelaPrincipal::buttonEnviar_Click);
//
// textBoxEnviar
//
this->textBoxEnviar->Location = System::Drawing::Point(12, 229);
this->textBoxEnviar->Multiline = true;
this->textBoxEnviar->Name = L"textBoxEnviar";
this->textBoxEnviar->Size = System::Drawing::Size(179, 20);
this->textBoxEnviar->TabIndex = 1;
this->textBoxEnviar->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &JanelaPrincipal::textBoxEnviar_KeyDown);
//
// textBoxReceber
//
this->textBoxReceber->Location = System::Drawing::Point(12, 12);
this->textBoxReceber->Multiline = true;
this->textBoxReceber->Name = L"textBoxReceber";
this->textBoxReceber->ReadOnly = true;
this->textBoxReceber->ScrollBars = System::Windows::Forms::ScrollBars::Horizontal;
this->textBoxReceber->Size = System::Drawing::Size(179, 208);
this->textBoxReceber->TabIndex = 2;
//
// buttonConectar
//
this->buttonConectar->Location = System::Drawing::Point(197, 12);
this->buttonConectar->Name = L"buttonConectar";
this->buttonConectar->Size = System::Drawing::Size(75, 23);
this->buttonConectar->TabIndex = 3;
this->buttonConectar->Text = L"Conectar!";
this->buttonConectar->UseVisualStyleBackColor = true;
this->buttonConectar->Click += gcnew System::EventHandler(this, &JanelaPrincipal::buttonConectar_Click);
//
// JanelaPrincipal
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(284, 261);
this->Controls->Add(this->buttonConectar);
this->Controls->Add(this->textBoxReceber);
this->Controls->Add(this->textBoxEnviar);
this->Controls->Add(this->buttonEnviar);
this->Name = L"JanelaPrincipal";
this->Text = L"JanelaPrincipal";
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void buttonEnviar_Click(System::Object^ sender, System::EventArgs^ e) {
String^ userInputSys = textBoxEnviar->Text;
std::string userInput = msclr::interop::marshal_as<std::string>(userInputSys);
if (userInput.size() > 0)
{
int sendResult = send(sock, userInput.c_str(), userInput.size() + 1, 0);
if (sendResult == SOCKET_ERROR)
{
textBoxReceber->Text = textBoxReceber->Text + "A mensagem não foi enviada!\r\n";
}
else
{
textBoxReceber->Text = textBoxReceber->Text + "Você: " + userInputSys + "\r\n";
}
}
textBoxEnviar->Text = "";
}
public: System::Void buttonConectar_Click(System::Object^ sender, System::EventArgs^ e) {
WSADATA data;
int r = WSAStartup(MAKEWORD(2, 2), &data);
if (r != 0)
{
textBoxReceber->Text = textBoxReceber->Text + "Falha Ao Iniciar Winsock!\r\n";
}
else
{
textBoxReceber->Text = textBoxReceber->Text + "Sucesso Ao Iniciar Winsock!\r\n";
}
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
textBoxReceber->Text = textBoxReceber->Text + "Falha ao criar o socket!\r\n";
WSACleanup();
}
else
textBoxReceber->Text = textBoxReceber->Text + "Sucesso! (socket)\r\n";
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(9000);
inet_pton(AF_INET, "127.0.0.1", &hint.sin_addr);
textBoxReceber->Text = textBoxReceber->Text + "Tentando conectar-se...\r\n";
int connectionresult = connect(sock, (sockaddr*)&hint, sizeof(hint));
if (connectionresult == SOCKET_ERROR)
{
textBoxReceber->Text = textBoxReceber->Text + "Não foi possível conectar ao servidor!\r\n";
closesocket(sock);
WSACleanup();
}
else
{
textBoxReceber->Text = textBoxReceber->Text + "Conectado com Sucesso!\r\n";
}
}
private: System::Void textBoxEnviar_KeyDown(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) {
if (e->KeyCode == Keys::Enter) {
buttonEnviar_Click(this, gcnew EventArgs());
}
}
};
}
JanelaPrincipal.cpp
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "iostream"
#include "windows.h"
#include "JanelaPrincipal.h"
using namespace System;
using namespace System::Windows::Forms;
[STAThread]
void main()
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
FakeWpp::JanelaPrincipal form;
Application::Run(% form);
}
Я просто хочу, чтобы клиент мог отправлять и получать сообщения