简介

每当我们想在 c 中进行套接字编程时,我们主要有两个选择;一种是在 Linux 中使用套接字 API,另一种是用于 Windows 的 Winsock,但有时我们有一些限制,因此我们想在 Windows 中使用 linux 套接字 API。我们将看到如何做同样的事情。

我们怎么做?

我们将在 windows 中安装 wsl 以在 windows 中使用 linux 包,进一步减少启动 wsl、创建文件夹、编译文件等繁琐的任务。我们将使用 vscode 使我们的任务变得简单。

1.在 Windows 中安装 WSL

  • 有关详细说明,请参阅此处的。

  • 右键单击 Windows 开始菜单图标,然后单击 Windows PowerShell(Admin)。

  • 在打开的窗口中,编写以下命令,将使用 ubuntu 发行版安装 wsl。您可以根据自己的喜好更改它:

wsl --install -d Ubuntu
  • 安装后会要求你设置用户名和密码。

  • 设置好用户名和密码后,你会看到wsl已经启动,现在编写如下命令:

sudo apt 更新 && sudo apt 升级
  • 之后,输入“exit”退出wsl,然后关闭PowerShell窗口。

2.设置 VSCode

  • 您可以使用任何开发 ide 或文本编辑器进行套接字编程,但 vscode 提供了一个简单的界面来使用扩展管理 wsl,因此我们将使用 vscode。

  • 打开特定文件夹的 vscode。

  • 然后从左侧打开扩展选项卡并搜索“ms-vscode-remote.remote-wsl”并安装它。 vscode_wsl_ext.png

  • 安装后,在左下角,你会看到远程wsl按钮,点击它,会打开下面的框,选择“在WSL中重新打开文件夹”,然后回车。 截图(289).png

3.编译和运行 Socket 编程代码

  • 从菜单栏中,打开终端选项卡并单击新建终端。

  • 第一次我们需要使用以下命令安装gcc和gdb:

sudo apt install gcc && sudo apt install gdb
  • 如您所见,以下 server.c 和 client.c 包含 windows 不支持的 sys/socket.h 文件。

  • 服务器文件

#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>

#define PORT 8080

int main(int argc, char *argv[]) {
    int server_fd, new_socket, valread;
    struct sockaddr_in address;
    int opt = 1;
    int addr_len = sizeof(address);
    char buffer[1024], response[1024];
    char *msgToSendBack = response;

    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("Socket Creation Failed");
        exit(EXIT_FAILURE);
    }

    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,&opt, sizeof(opt))) {
        perror("Set Can't be attached");
        exit(EXIT_FAILURE);
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    if (bind(server_fd, (struct sockaddr *) &address, sizeof(address)) < 0) {
        perror("Can't Bind");
        exit(EXIT_FAILURE);
    }

    if (listen(server_fd, 3) < 0) {
        perror("Can't Listen");
        exit(EXIT_FAILURE);
    }

    if ((new_socket = accept(server_fd, (struct sockaddr*)&address, (socklen_t*)&addr_len)) < 0) {
        perror("Connection can't be accpeted");
        exit(EXIT_FAILURE);
    }
    while(1) {
        valread = read(new_socket, buffer, 1024);
        buffer[valread] = '\0';
        printf("Incoming Message: %s\n", buffer);

        if (strncasecmp("How are you?",buffer, strlen("How are you?")) == 0) {
            send(new_socket, "I am fine", strlen("I am fine"), 0);
        }
        else {
            strcpy(msgToSendBack, buffer);
            strcat(msgToSendBack, " Message Received");
            send(new_socket, msgToSendBack, strlen(msgToSendBack), 0);
        }

        printf("Response Message Sent\n");
        fflush(stdout);

        memset(buffer, 0, 1024);
        memset(response, 0, 1024);
    }

    return 0;
}
  • 客户端.c
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>

#define PORT 8080

int main(int argc, char *argv[]) {
    int sock = 0, valread;
    struct sockaddr_in serv_addr;
    char *exit_msg = "exit", *msg;
    char buffer[1024] = {0};

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("\n Socket Connection Error");
        return -1;
    }

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);

    if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
        printf("\n Invalid address");
        return -1;
    }

    if (connect(sock, (struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0) {
        printf("\n Connection Failed\n");
        return -1;
    }

    while (1) {
        printf("Enter Message for server:");
        scanf("%[^\n]%*c", msg);

        if(!strcmp(msg, exit_msg)) {
            close(sock);
            return 0;
        }

        send(sock, msg, strlen(msg), 0);
        valread = read(sock, buffer, 1024);
        printf("From Server: %s\n", buffer);
    }

    return 0;
}
  • 现在,使用我们之前打开的终端窗口,编写以下命令来编译文件
gcc server.c -o 服务器
gcc client.c -o 客户端
  • 现在,使用以下命令在同一终端窗口中运行服务器文件
。/服务器
  • 打开另一个终端窗口并运行客户端文件。
。/客户
  • 这样你就可以在windows中运行linux socket api了。

快乐编码 :)

Logo

更多推荐