我一直在尝试在C中创建套接字程序。我的目标是尝试执行多线程服务器 - 客户端消息应用程序。所以我可以将多客户端连接到服务器并从服务器发送消息。
我的代码工作但不是我想要的。例如,如果我运行服务器只有一个客户端,它会向客户端发送消息,但是当我尝试连接另一个客户端时,它会逐个发送消息。例如,如果我在服务器中写东西并发送,它首先是客户端;如果我写了一些东西并再次发送,那就是第二个客户端。我需要选择我想发送消息的客户端,但我无法弄明白。你能帮帮我吗?
这是服务器代码
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <process.h>
#pragma comment(lib, "Ws2_32.lib")
char buffer[100];
int MyFunction(void* Arg)
{
SOCKET Client = (*(int *)Arg);
while (1)
{
//int Socket = (*(int *)Arg);
printf("-> ");
gets(buffer);
send(Client, buffer, 100, 0);
}
_endthreadex(0);
}
/*-------------------------------------------------------------------- */
void main(void)
{
int a, b, c, d;
int port;
struct sockaddr_in serv_addr, cli_addr;
SOCKET Server;
SOCKET Client;
int clilen = sizeof(cli_addr);
// SOCKET INITIALISATION
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(1, 1), &WsaDat) != 0)
{
printf("\n\n WSA Initialization failed!");
exit(1);
}
// SOCKET
Server = socket(AF_INET, SOCK_STREAM, 0);
if (Server == INVALID_SOCKET)
{
printf("\n\n Socket creation failed!");
exit(1);
}
else
printf("\n\n SOCKET IS CREATED SUCCESSFULLY...");
// SERVER ADDRESS
serv_addr.sin_family = AF_INET;
printf("\n ENTER THE SERVER IP ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);
serv_addr.sin_addr.S_un.S_un_b.s_b1 = a;
serv_addr.sin_addr.S_un.S_un_b.s_b2 = b;
serv_addr.sin_addr.S_un.S_un_b.s_b3 = c;
serv_addr.sin_addr.S_un.S_un_b.s_b4 = d;
printf("\n ENTER THE PORT NO ");
scanf_s("%d", &port);
serv_addr.sin_port = htons(port);
// BIND
if (bind(Server, (struct sockaddr *)(&serv_addr), sizeof(serv_addr)) == SOCKET_ERROR)
{
printf("\n\n Attempt to bind failed!STOP!!!");
}
else
printf("\n\n BIND PROCESS IS CREATED SUCCESSFULLY...\n ");
// LISTEN
if (listen(Server, 5) == SOCKET_ERROR)
printf("\n Error in Listenning The Socket!\n");
/*---------------------------------------------------*/
int i = 0;
while (1)
{
printf("\n SERVER IS RUNNING...\n ");
printf("Client %d is connected!\n", i);
Client = accept(Server, (struct sockaddr*)&cli_addr, &clilen);
_beginthread(MyFunction, 0, (void *)&Client);
i++;
}
_getch();
}
这是客户端代码:
#include<stdio.h>
#include<conio.h>
#include<winsock2.h>
#include<process.h>
#pragma comment(lib, "Ws2_32.lib")
char buffer[100];
void MyFunction(void * Arg)
{
SOCKET Socket = (*(int *)Arg);
while (1)
{
recv(Socket, buffer, 100, 0);
printf("Server: %s\n", buffer);
}
_endthread();
}
void main(void)
{
WSADATA WsaDat;
if (WSAStartup(MAKEWORD(2, 0), &WsaDat) != 0)
{
printf("\n WSA Initialization failed.");
exit(1);
}
struct STRUCTADDR
{
short sin_family;
short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct STRUCTADDR p1_addr, cli_addr;
int clilen = sizeof(cli_addr);
p1_addr.sin_family = AF_INET;
int a, b, c, d;
printf("\n\n ENTER THE SERVER IP ");
scanf_s("%d %d %d %d", &a, &b, &c, &d);
p1_addr.sin_addr.S_un.S_un_b.s_b1 = a;
p1_addr.sin_addr.S_un.S_un_b.s_b2 = b;
p1_addr.sin_addr.S_un.S_un_b.s_b3 = c;
p1_addr.sin_addr.S_un.S_un_b.s_b4 = d;
int port;
printf("\n\n ENTER THE PORT NO ");
scanf_s("%d", &port);
p1_addr.sin_port = htons(port);
/*--------------------------------------------*/
SOCKET Socket;
Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Socket == INVALID_SOCKET)
{
printf("\n Socket creation failed.");
exit(1);
}
printf("\n SOCKET IS CREATED SUCCESSFULLY");
if (connect(Socket, (SOCKADDR *)(&p1_addr), sizeof(p1_addr)) != 0)
{
printf("\n Failed to establish connection with server...");
}
else
//while (1)
//{
printf("\n\n CONNECTED\n");
_beginthread(MyFunction, 0, (void *)&Socket);
//}
_getch();
}
答案 0 :(得分:0)
在服务器中接受套接字时,需要在队列或数组中添加接受的套接字,而不是直接将其传递给线程函数。您也可以选择存储accept()调用返回的每个对等体的IP地址,以便在想要向其发送数据时识别给定的客户端