基于Windows系统的C语言socket客户端和服务器程序示例,该示例使用多线程解决了recv和send函数的阻塞问题,可以让程序同时进行收发通信。
时间: 2024-02-27 15:51:41 浏览: 20
下面是一个基于Windows系统的C语言socket客户端和服务器程序示例,使用了多线程来解决recv和send函数的阻塞问题,可以让程序同时进行收发通信。
服务器端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#define PORT 8888
#define MAX_CLIENTS 30
SOCKET clients[MAX_CLIENTS];
int client_count = 0;
// 多线程处理函数
DWORD WINAPI clientHandler(LPVOID lpParam) {
SOCKET client = (SOCKET) lpParam;
char buffer[1024];
int bytesReceived;
while (1) {
// 接收客户端发送的消息
bytesReceived = recv(client, buffer, sizeof(buffer), 0);
if (bytesReceived <= 0) {
// 客户端断开连接
printf("Client disconnected\n");
closesocket(client);
return 0;
}
// 将收到的消息发送给所有客户端
for (int i = 0; i < client_count; i++) {
if (clients[i] != client) {
send(clients[i], buffer, bytesReceived, 0);
}
}
}
}
int main() {
WSADATA wsa;
SOCKET serverSocket, clientSocket;
struct sockaddr_in serverAddr, clientAddr;
int clientAddrSize = sizeof(clientAddr);
HANDLE threadHandle;
// 初始化Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("WSAStartup failed\n");
return 1;
}
// 创建服务端Socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
printf("Failed to create socket: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
// 绑定地址和端口
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(PORT);
if (bind(serverSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) < 0) {
printf("Bind failed: %d\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 监听连接
listen(serverSocket, 5);
printf("Server started on port %d\n", PORT);
// 接受客户端连接并创建线程处理
while (1) {
clientSocket = accept(serverSocket, (struct sockaddr*) &clientAddr, &clientAddrSize);
if (clientSocket == INVALID_SOCKET) {
printf("Accept failed: %d\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 将客户端Socket添加到数组中
if (client_count < MAX_CLIENTS) {
clients[client_count++] = clientSocket;
} else {
printf("Too many clients\n");
closesocket(clientSocket);
}
// 创建线程处理客户端连接
threadHandle = CreateThread(NULL, 0, clientHandler, (LPVOID) clientSocket, 0, NULL);
if (threadHandle == NULL) {
printf("CreateThread failed: %d\n", GetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
}
closesocket(serverSocket);
WSACleanup();
return 0;
}
```
客户端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <windows.h>
#define SERVER_IP "127.0.0.1"
#define PORT 8888
// 多线程处理函数
DWORD WINAPI recvHandler(LPVOID lpParam) {
SOCKET serverSocket = (SOCKET) lpParam;
char buffer[1024];
int bytesReceived;
while (1) {
// 接收服务器发送的消息
bytesReceived = recv(serverSocket, buffer, sizeof(buffer), 0);
if (bytesReceived <= 0) {
// 服务器断开连接
printf("Server disconnected\n");
closesocket(serverSocket);
exit(0);
}
printf("Received: %s\n", buffer);
}
}
int main() {
WSADATA wsa;
SOCKET serverSocket;
struct sockaddr_in serverAddr;
HANDLE threadHandle;
char message[1024];
// 初始化Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("WSAStartup failed\n");
return 1;
}
// 创建客户端Socket
serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
printf("Failed to create socket: %d\n", WSAGetLastError());
WSACleanup();
return 1;
}
// 连接服务器
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(SERVER_IP);
serverAddr.sin_port = htons(PORT);
if (connect(serverSocket, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) < 0) {
printf("Connect failed: %d\n", WSAGetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 创建线程接收服务器消息
threadHandle = CreateThread(NULL, 0, recvHandler, (LPVOID) serverSocket, 0, NULL);
if (threadHandle == NULL) {
printf("CreateThread failed: %d\n", GetLastError());
closesocket(serverSocket);
WSACleanup();
return 1;
}
// 发送消息给服务器
while (1) {
fgets(message, sizeof(message), stdin);
send(serverSocket, message, strlen(message), 0);
}
closesocket(serverSocket);
WSACleanup();
return 0;
}
```