《TCP/IP网络编程》
最近看了下《TCP/IP网络编程》这本书,想自己实现一下TCP通信的客户端和服务器端
下面是源代码
Ser.c
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
struct CustomMessage {
char university[4]; // "AHU\0"
char major[32]; // 专业
char data[256]; // 消息数据
};
int main() {
// 初始化 Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "Failed to initialize Winsock\n");
return 1;
}
// 创建套接字
SOCKET server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == INVALID_SOCKET) {
fprintf(stderr, "Socket creation failed\n");
WSACleanup();
return 1;
}
// 绑定端口
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(8888);
if (bind(server_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == SOCKET_ERROR) {
fprintf(stderr, "Bind failed\n");
closesocket(server_socket);
WSACleanup();
return 1;
}
// 监听
if (listen(server_socket, SOMAXCONN) == SOCKET_ERROR) {
fprintf(stderr, "Listen failed\n");
closesocket(server_socket);
WSACleanup();
return 1;
}
printf("Server listening on port 8888...\n");
while (1) {
// 接受连接
SOCKET client_socket = accept(server_socket, NULL, NULL);
if (client_socket == INVALID_SOCKET) {
fprintf(stderr, "Accept failed\n");
closesocket(server_socket);
WSACleanup();
return 1;
}
// 接收自定义消息
struct CustomMessage received_message;
int bytes_received = recv(client_socket, (char*)&received_message, sizeof(struct CustomMessage), 0);
if (bytes_received > 0) {
printf("Received Message:\n");
printf("University: %s\n", received_message.university);
printf("Major: %s\n", received_message.major);
printf("Data: %s\n", received_message.data);
}
else if (bytes_received == 0) {
printf("Client disconnected\n");
closesocket(client_socket);
continue; // 继续等待下一个连接
}
else {
fprintf(stderr, "Receive failed\n");
closesocket(client_socket);
continue; // 继续等待下一个连接
}
// 关闭客户端套接字
closesocket(client_socket);
}
// 关闭服务器套接字
closesocket(server_socket);
// 清理 Winsock
WSACleanup();
return 0;
}
Cli.c
#include <stdio.h>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include<tchar.h>
#pragma comment(lib, "ws2_32.lib")
struct CustomMessage {
char university[4]; // "AHU\0"
char major[32]; // 专业
char data[256]; // 消息数据
};
int main() {
// 初始化 Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "Failed to initialize Winsock\n");
return 1;
}
// 创建套接字
SOCKET client_socket = socket(AF_INET, SOCK_STREAM, 0);
if (client_socket == INVALID_SOCKET) {
fprintf(stderr, "Socket creation failed\n");
WSACleanup();
return 1;
}
// 连接服务器
struct sockaddr_in server_address;
server_address.sin_family = AF_INET;
if (InetPton(AF_INET, _T("127.0.0.1"), &(server_address.sin_addr)) != 1) {
fprintf(stderr, "Invalid IP address\n");
closesocket(client_socket);
WSACleanup();
return 1;
}
server_address.sin_port = htons(8888);
if (connect(client_socket, (struct sockaddr*)&server_address, sizeof(server_address)) == SOCKET_ERROR) {
fprintf(stderr, "Connection failed\n");
closesocket(client_socket);
WSACleanup();
return 1;
}
while (1) {
// 获取用户输入的消息
printf("请输入要发送的消息 (输入 exit 结束): ");
struct CustomMessage message_to_send;
fgets(message_to_send.data, sizeof(message_to_send.data), stdin);
message_to_send.data[strcspn(message_to_send.data, "\n")] = '\0'; // 移除换行符
strcpy_s(message_to_send.university, sizeof(message_to_send.university), "AHU");//以AHU开头
strcpy_s(message_to_send.major, sizeof(message_to_send.major), "CS"); // 设置专业为"CS"
// 发送自定义消息
int bytes_sent = send(client_socket, (const char*)&message_to_send, sizeof(struct CustomMessage), 0);
if (bytes_sent == SOCKET_ERROR) {
fprintf(stderr, "Send failed\n");
closesocket(client_socket);
WSACleanup();
return 1;
}
// 如果用户输入 "exit",结束循环
if (strcmp(message_to_send.data, "exit") == 0) {
break;
}
}
// 关闭客户端套接字
closesocket(client_socket);
// 清理 Winsock
WSACleanup();
return 0;
}
运行
先运行Ser.c,再运行Cli.c
完工!