2017-05-01 197 views
0

當我連接多個客戶端時,我將如何發送到特定客戶端。我想到了sendto();但我在同一個插座上運行它們,我不確定如何存儲其地址爲sendto()的地址。所以也許我接受多個客戶的方式不太好?發送()到特定客戶端C WInSock

我的服務器代碼:

#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); 

返回0; }

+0

你有一個* listen *套接字,但是每個連接的客戶都有它自己的*連接*套接字(這是'accept()'返回的)。要發送到特定的客戶端,只需使用正確的套接字(爲該客戶端返回一個'accept()')。然而,你確實只有一個'clientnum'的全局副本,這可能會引起混淆(當一個線程讀取它時,它的值可能與線程創建時的值不一樣)。 – Dmitri

+0

好的,我會考慮使用不同的連接套接字,謝謝!而clientnum的工作原理,並顯示每個客戶端相應的客戶端號碼。我唯一的其他問題是檢測客戶端斷開連接和客戶端 - ;根本不起作用。 – Jimmmmmy

+0

在我看來,你正處於正確的軌道上,在你的主內監聽並在單獨的線程中處理客戶端。您還將正確的套接字傳遞給線程來處理客戶端。如果你想從一個客戶端發送數據到另一個客戶端,你可能只需要一個全部連接客戶端的全局列表? –

回答

0

您將通過send將數據發送到連接到該客戶端的套接字的特定客戶端。

這就是你已經在做的事情。

相關問題