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; }
你有一個* listen *套接字,但是每個連接的客戶都有它自己的*連接*套接字(這是'accept()'返回的)。要發送到特定的客戶端,只需使用正確的套接字(爲該客戶端返回一個'accept()')。然而,你確實只有一個'clientnum'的全局副本,這可能會引起混淆(當一個線程讀取它時,它的值可能與線程創建時的值不一樣)。 – Dmitri
好的,我會考慮使用不同的連接套接字,謝謝!而clientnum的工作原理,並顯示每個客戶端相應的客戶端號碼。我唯一的其他問題是檢測客戶端斷開連接和客戶端 - ;根本不起作用。 – Jimmmmmy
在我看來,你正處於正確的軌道上,在你的主內監聽並在單獨的線程中處理客戶端。您還將正確的套接字傳遞給線程來處理客戶端。如果你想從一個客戶端發送數據到另一個客戶端,你可能只需要一個全部連接客戶端的全局列表? –