用winsock编写一个C/S通讯
时间: 2023-07-18 10:24:27 浏览: 42
好的,以下是一个简单的基于 Winsock 的 C/S 通讯例子,其中客户端和服务器端都是使用 C 语言编写的。
服务器端代码:
```c
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsa;
SOCKET server_sock, client_sock;
struct sockaddr_in server_addr, client_addr;
int client_addr_size = sizeof(client_addr);
char buffer[1024] = {0};
// 初始化 Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
// 创建服务器端套接字
if ((server_sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket : %d", WSAGetLastError());
WSACleanup();
return 1;
}
// 初始化服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(8888);
// 绑定服务器端套接字
if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == SOCKET_ERROR) {
printf("Bind failed with error code : %d", WSAGetLastError());
closesocket(server_sock);
WSACleanup();
return 1;
}
// 监听客户端连接请求
listen(server_sock, 3);
printf("Server listening on port 8888...\n");
// 接收客户端连接并处理
while ((client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_addr_size)) != INVALID_SOCKET) {
printf("Connection accepted from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
// 接收客户端数据并回复
while (1) {
// 接收客户端数据
int num_bytes = recv(client_sock, buffer, sizeof(buffer), 0);
if (num_bytes == SOCKET_ERROR) {
printf("recv failed with error code : %d", WSAGetLastError());
closesocket(client_sock);
WSACleanup();
return 1;
}
if (num_bytes == 0) {
printf("Connection closed by client.\n");
closesocket(client_sock);
break;
}
// 处理客户端数据
buffer[num_bytes] = '\0';
printf("Received message from %s:%d: %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer);
// 回复客户端数据
if (send(client_sock, buffer, num_bytes, 0) == SOCKET_ERROR) {
printf("send failed with error code : %d", WSAGetLastError());
closesocket(client_sock);
WSACleanup();
return 1;
}
}
}
// 关闭服务器端套接字
closesocket(server_sock);
// 清理 Winsock
WSACleanup();
return 0;
}
```
客户端代码:
```c
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsa;
SOCKET sock;
struct sockaddr_in server_addr;
char buffer[1024] = {0};
// 初始化 Winsock
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) {
printf("Failed. Error Code : %d", WSAGetLastError());
return 1;
}
// 创建客户端套接字
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
printf("Could not create socket : %d", WSAGetLastError());
WSACleanup();
return 1;
}
// 初始化服务器地址
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
// 连接服务器端套接字
if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
printf("Connect failed with error code : %d", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}
printf("Connected to server.\n");
// 发送数据到服务器端并接收回复
while (1) {
// 发送数据到服务器端
printf("Enter message: ");
gets_s(buffer, sizeof(buffer));
if (send(sock, buffer, strlen(buffer), 0) == SOCKET_ERROR) {
printf("send failed with error code : %d", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}
// 接收服务器端回复
int num_bytes = recv(sock, buffer, sizeof(buffer), 0);
if (num_bytes == SOCKET_ERROR) {
printf("recv failed with error code : %d", WSAGetLastError());
closesocket(sock);
WSACleanup();
return 1;
}
if (num_bytes == 0) {
printf("Connection closed by server.\n");
closesocket(sock);
break;
}
// 处理服务器端回复
buffer[num_bytes] = '\0';
printf("Received message from server: %s\n", buffer);
}
// 关闭客户端套接字
closesocket(sock);
// 清理 Winsock
WSACleanup();
return 0;
}
```
这个例子简单地实现了一个回显服务器,客户端向服务器发送数据,服务器接收到数据后将其回传给客户端。你可以在这个例子的基础上进行扩展和修改,以满足你的具体需求。