2017-05-01 3 views
0

Comment envoyer à un client spécifique lorsque plusieurs clients sont connectés. J'ai pensé à sendto(); Mais je cours tous sur le même socket et je ne suis pas sûr d'un moyen de stocker leur addr pour sendto(). Alors peut-être que ma façon d'accepter plusieurs clients n'est pas très bonne?send() vers un client spécifique C WInSock

Mon Code Serveur:

#include "stdafx.h" 
#include <stdio.h> 
#include <winsock.h> 
#include <stdlib.h> 
#include <string.h> 
#include <conio.h> 
#pragma comment(lib,"ws2_32.lib") //Winsock Library 
#define _WIN32_WINNIT 0x0500 
#include <windows.h> 
WSADATA wsa; 
SOCKET sock, newsock; 
int c; 
int clientnum; 
struct sockaddr_in server, client; 

DWORD WINAPI ProcessClient(LPVOID lpParam) { 
    SOCKET newSock = (SOCKET)lpParam; 
    // Send and receive data. 
    char buf[256]; 
    char newbuf[256]; 
    char cnumchar[5]; 
    strcpy(buf, "Hello Client #: "); 
    itoa(clientnum, cnumchar, 10); 
    strcat(buf, cnumchar); 
    sendto(newSock, buf, sizeof(buf), 0, NULL, NULL); 
    char sendbuf[256]; 
    strcpy(sendbuf, "a"); 
    while (1) 
    { 
     if (recv(newSock, newbuf, sizeof(newbuf), 0) == 0 || recv(newSock, newbuf, sizeof(newbuf), 0) == -1) { 
      printf("\nClient disconnected"); 
      clientnum--; 
     } 
     else if (send(newSock, sendbuf, sizeof(sendbuf), 0) == 0 || send(newSock, sendbuf, sizeof(sendbuf), 0) == -1) { 
      printf("\nClient Disconnected!"); 
      clientnum--; 
     } 



    } 

} 

int main() 
{ 

    printf("Initializing Winsock...\n"); 
    int ret = WSAStartup(MAKEWORD(2, 2), &wsa); 
    if (ret != 0) 
    { 
     printf("Initialization Failed. Error: %d", ret); 
     return 1; 
    } 
    printf("Initialized.\n"); 

    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 
    if (sock == INVALID_SOCKET) { 
     printf("Could not create socket! Error: %d\n", WSAGetLastError()); 
     return 1; 
    } 
    //textcolor(2); 
    printf("Socket Created!\n"); 

    memset(&server, 0, sizeof(server)); 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(3939); 

    //bind 
    if (bind(sock, (struct sockaddr *)&server, sizeof(server)) == SOCKET_ERROR) { 
     printf("Bind failed! Error: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     getch(); 
     return 1; 
    } 
    printf("Binded!\n"); 

    // listen 
    if (listen(sock, 1) == SOCKET_ERROR) { 
     printf("Listen failed! Error: %d\n", WSAGetLastError()); 
     closesocket(sock); 
     return 1; 
    } 
    printf("Now Listening...\n"); 
    do { 
     newsock = SOCKET_ERROR; 
     do { 
      newsock = accept(sock, NULL, NULL); 
     } while (newsock == SOCKET_ERROR); 
     printf("Client Connected!"); 
     DWORD dwThreadId; 
     CreateThread(NULL, 0, ProcessClient, (LPVOID)newsock, 0, &dwThreadId); 
     clientnum++; 
    } while (true); 

return 0; }

+0

Vous avez une socket * listening *, mais chaque client connecté a sa propre socket * connection * (qui est ce que 'accept()' renvoie). Pour envoyer à un client particulier, utilisez simplement la bonne socket (celle 'accept()' retournée pour ce client). Vous n'avez cependant qu'une seule copie globale de 'clientnum', ce qui peut être source de confusion (lorsqu'un thread le lit, sa valeur peut ne pas être la même que lors de la création du thread). – Dmitri

+0

Ok je vais regarder en utilisant les différentes prises de connexion merci! Et la chose clientnum fonctionne comme prévu et montre à chaque client son numéro de client correspondant. Mon seul autre problème est la détection des déconnexions client et clientnum--; ne fonctionne pas du tout. – Jimmmmmy

+0

Il me semble que vous êtes sur la bonne voie avec l'écoute dans votre main et la manipulation des clients dans des discussions séparées. Vous passez également le socket droit au thread pour gérer le client. Si vous souhaitez envoyer des données d'un client à un autre, vous avez peut-être besoin d'une liste globale de tous vos clients connectés? –

Répondre

0

Vous enverriez des données à un client spécifique par send en l'insérant dans un socket connecté à ce client.

Ce que vous faites déjà.