So habe ich diese winsock
Anwendung (ein Server, mehrere Clients akzeptieren), wo im Haupt-Thread ich den Socket einrichten und erstellen Sie einen anderen Thread, wo ich für Clients (listen_for_clients
Funktion).Übergabe von Daten an einen anderen Thread in einer C++ Winsock App
Ich bekomme auch ständig Daten von einem Gerät im Haupt-Thread, die ich anschließend zu Char-Arrays (Puffer) von Client
Objekte verketten (BroadcastSample
Funktion). Zur Zeit erstelle ich einen Thread für jeden verbundenen Client (ProcessClient
Funktion), wo ich ein Client
Objekt initialisiere und es zu einem globalen Vektor von Clients verschiebe, nach dem ich Daten an diesen Client über den Socket immer dann senden, wenn der Puffer im entsprechenden Client
Objekt 4000 überschreitet Figuren.
Gibt es eine Möglichkeit, kann ich Daten aus dem Haupt-Thread zu den separaten Client-Threads senden, so brauche ich nicht Strukturen/Klassen (auch ein grünes Licht senden, wenn ich die bereits gesammelten Daten senden möchte) und Auch wenn ich einen globalen Container mit Objekten verwalte, was ist ein guter Weg, um ein getrenntes Client-Objekt daraus zu entfernen, ohne das Programm zu stürzen, weil ein anderer Thread den gleichen Container verwendet?
struct Client{
int buffer_len;
char current_buffer[5000];
SOCKET s;
};
std::vector<Client*> clientBuffers;
DWORD WINAPI listen_for_clients(LPVOID Param)
{
SOCKET client;
sockaddr_in from;
int fromlen = sizeof(from);
char buf[100];
while(true)
{
client = accept(ListenSocket,(struct sockaddr*)&from,&fromlen);
if(client != INVALID_SOCKET)
{
printf("Client connected\n");
unsigned dwThreadId;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, &ProcessClient, (void*)client, 0, &dwThreadId);
}
}
closesocket(ListenSocket);
WSACleanup();
ExitThread(0);
}
unsigned __stdcall ProcessClient(void *data)
{
SOCKET ClientSocket = (SOCKET)data;
Client * a = new Client();
a->current_buffer[0] = '\0';
a->buffer_len = 0;
a->s = ClientSocket;
clientBuffers.push_back(a);
char szBuffer[255];
while(true)
{
if(a->buffer_len > 4000)
{
send(ClientSocket,a->current_buffer,sizeof(a->current_buffer),0);
memset(a->current_buffer,0,5000);
a->buffer_len = 0;
a->current_buffer[0] = '\0';
}
}
exit(1);
}
//function below is called only in main thread, about every 100ms
void BroadcastSample(Sample s)
{
for(std::vector<Client*>::iterator it = clientBuffers.begin(); it != clientBuffers.end(); it++)
{
strcat((*it)->current_buffer,s.to_string);
(*it)->buffer_len += strlen(s.to_string);
}
}
Was machen die per-socked-Fäden für Sie? dauert der Aufruf 'send (socked, buffer, size, 0)' lange? Ich glaube nicht, dass du etwas gewinnst, wenn du diese Threads hast. – Jfevold
@Jfevold: als allgemeine Regel, wenn Sie mehrere Clients haben alle I/O sollte entweder in separaten Threads oder asynchron erfolgen. Sonst könnte ein einzelner missgebildeter Klient möglicherweise alles zum Schreien bringen. –
Wenn Sie eine ausreichend aktuelle Version von C++ verwenden, sollten Sie wahrscheinlich die Threading-Unterstützung verwenden, die ohne Zweifel Thread-sichere Warteschlangen und ähnliches enthält. Wenn Sie die Windows-API verwenden möchten, kann [verknüpfte einfach verknüpfte Listen] (https://msdn.microsoft.com/en-us/library/windows/desktop/ms684121 (v = vs.85) .aspx) möglicherweise eine sein geeignete Option. –