C语言WinSock学习笔记

下面我来详细讲解一下《C语言WinSock学习笔记》的完整攻略。

一、WinSock是什么

WinSock (Windows Sockets) 是一种技术,允许应用程序通过 TCP/IP 协议来进行网络通信,是 Windows 操作系统自带的一个 API。WinSock 可以使用基于 TCP 或者 UDP 协议的 Socket 通信方式来实现网络应用。

二、WinSock的基本使用

  1. 加载WinSock库

在使用WinSock API之前,需要加载WinSock库,代码如下所示:

#include <WinSock2.h>  // 加载WinSock库
#pragma comment(lib, "ws2_32.lib")  // 链接到WinSock库文件
  1. 初始化WinSock

在使用WinSock API之前,我们需要调用WSAStartup()函数来初始化WinSock库,代码如下所示:

WSADATA wsaData;
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
    printf("WSAStartup failed!\n");
    return 1;
}
  1. 创建Socket

创建Socket使用WinSock API中的socket()函数,代码如下所示:

SOCKET sock;
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sock == INVALID_SOCKET) {
    printf("socket failed!\n");
    return 1;
}
  1. 连接服务器

使用connect()函数连接到服务器,代码如下所示:

SOCKADDR_IN serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddr.sin_port = htons(12345);
if(connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
    printf("connect failed!\n");
    closesocket(sock);
    return 1;
}
  1. 发送和接收数据

使用send()函数发送数据,使用recv()函数接收数据,代码如下所示:

char sendbuf[1024] = "hello";
char recvbuf[1024];
int ret = 0;
ret = send(sock, sendbuf, strlen(sendbuf), 0);
if(ret == SOCKET_ERROR) {
    printf("send failed!\n");
    closesocket(sock);
    return 1;
}
ret = recv(sock, recvbuf, sizeof(recvbuf), 0);
if(ret == SOCKET_ERROR) {
    printf("recv failed!\n");
    closesocket(sock);
    return 1;
}
printf("recvbuf: %s\n", recvbuf);
  1. 关闭Socket

使用closesocket()函数关闭Socket,代码如下所示:

closesocket(sock);

三、示例1:TCP客户端

下面的示例程序是一个简单的TCP客户端,连接到服务器并发送一条"hello"消息,然后等待服务器的回复。

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

int main(void) {
    WSADATA wsaData;
    int ret = 0;
    SOCKET sock = INVALID_SOCKET;
    SOCKADDR_IN serverAddr;
    char sendbuf[1024] = "hello";
    char recvbuf[1024];

    // 加载WinSock库
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("WSAStartup failed!\n");
        return 1;
    }

    // 创建Socket
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == INVALID_SOCKET) {
        printf("socket failed!\n");
        return 1;
    }

    // 连接服务器
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    serverAddr.sin_port = htons(12345);
    if(connect(sock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        printf("connect failed!\n");
        closesocket(sock);
        return 1;
    }

    // 发送数据
    ret = send(sock, sendbuf, strlen(sendbuf), 0);
    if(ret == SOCKET_ERROR) {
        printf("send failed!\n");
        closesocket(sock);
        return 1;
    }

    // 接收数据
    ret = recv(sock, recvbuf, sizeof(recvbuf), 0);
    if(ret == SOCKET_ERROR) {
        printf("recv failed!\n");
        closesocket(sock);
        return 1;
    }
    printf("recvbuf: %s\n", recvbuf);

    // 关闭Socket
    closesocket(sock);

    // 释放WinSock库资源
    WSACleanup();

    return 0;
}

四、示例2:TCP服务器

下面的示例程序是一个简单的TCP服务器,等待客户端连接,收到客户端发送的消息后回复一条"world"消息,然后关闭连接。

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")

int main(void) {
    WSADATA wsaData;
    int ret = 0;
    SOCKET listenSock = INVALID_SOCKET;
    SOCKET clientSock = INVALID_SOCKET;
    SOCKADDR_IN serverAddr;
    SOCKADDR_IN clientAddr;
    int clientAddrLen = sizeof(clientAddr);
    char recvbuf[1024];
    char sendbuf[1024] = "world";

    // 加载WinSock库
    if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
        printf("WSAStartup failed!\n");
        return 1;
    }

    // 创建Socket
    listenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(listenSock == INVALID_SOCKET) {
        printf("socket failed!\n");
        return 1;
    }

    // 绑定IP和端口
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    serverAddr.sin_port = htons(12345);
    if(bind(listenSock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        printf("bind failed!\n");
        closesocket(listenSock);
        return 1;
    }

    // 监听端口
    if(listen(listenSock, SOMAXCONN) == SOCKET_ERROR) {
        printf("listen failed!\n");
        closesocket(listenSock);
        return 1;
    }

    // 等待客户端连接
    printf("waiting for clients...\n");
    clientSock = accept(listenSock, (SOCKADDR*)&clientAddr, &clientAddrLen);
    if(clientSock == INVALID_SOCKET) {
        printf("accept failed!\n");
        closesocket(listenSock);
        return 1;
    }
    printf("client accept from: %s:%d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port));

    // 接收数据
    ret = recv(clientSock, recvbuf, sizeof(recvbuf), 0);
    if(ret == SOCKET_ERROR) {
        printf("recv failed!\n");
        closesocket(clientSock);
        closesocket(listenSock);
        return 1;
    }
    printf("recvbuf: %s\n", recvbuf);

    // 发送数据
    ret = send(clientSock, sendbuf, strlen(sendbuf), 0);
    if(ret == SOCKET_ERROR) {
        printf("send failed!\n");
        closesocket(clientSock);
        closesocket(listenSock);
        return 1;
    }

    // 关闭连接
    closesocket(clientSock);
    closesocket(listenSock);

    // 释放WinSock库资源
    WSACleanup();

    return 0;
}

以上就是《C语言WinSock学习笔记》的完整攻略,希望对你有帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言WinSock学习笔记 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • 详解C++程序中定义struct结构体的方法

    下面我将详细讲解如何在C++程序中定义struct结构体。 1. 概述 在C++中,struct是一种用户自定义的数据类型,它可以将多个不同类型的数据成员组合在一起,形成一个数据结构。在C++中,我们可以使用struct关键字来定义一个结构体,然后在程序中实例化一个结构体对象,可以使用结构体对象来访问结构体中的数据成员,从而完成对数据的处理。 2. 定义结构…

    C 2023年5月30日
    00
  • CCleaner如何查看版本号?CCleaner查看版本号方法

    CCleaner是一款非常流行的系统清理工具,使用最多的用户估计都想知道如何查看它的版本号。下面是完整的攻略,包含了CCleaner的版本号查看方法和两条示例说明。 CCleaner如何查看版本号? 要查看CCleaner的版本号,可以按照以下步骤操作: 打开CCleaner应用程序。 在第一次启动应用程序的界面,在欢迎界面的左上角可以看到版本号,如“CCl…

    C 2023年5月23日
    00
  • Python JSON模块的使用详情

    Python JSON模块的使用详情 什么是JSON? JSON是JavaScript对象表示法(JavaScript Object Notation)的缩写,是一种轻量级的数据交换格式。它以易于阅读和编写的文本格式为基础,通常用于在网络之间传输数据。在Python中,有一个常用的模块叫做json,可以方便地对JSON数据进行编码和解码操作。 序列化与反序列…

    C 2023年5月23日
    00
  • C 内存管理

    C 内存管理 C 语言是一门直接操作内存的语言,因此内存管理是 C 语言中非常重要的概念。在 C 语言中,开辟内存空间需要使用 malloc、calloc 或 realloc 函数,释放内存空间需要使用 free 函数。下面我们来详细讲解一下 C 内存管理的完整使用攻略。 动态内存分配 在 C 语言中,动态内存分配是指在程序运行期间,根据需要动态地申请内存空…

    C 2023年5月10日
    00
  • python基础教程之popen函数操作其它程序的输入和输出示例

    Python基础教程之popen函数操作其他程序的输入和输出示例 什么是popen函数? popen函数是Python中一个用于打开一个进程作为管道的函数。通过它,你可以利用子进程的标准输入、输出、错误流和父进程之间的通信。popen函数本质上使用子进程来读取、写入或处理数据。 如何使用popen函数? 使用popen函数可以通过以下步骤来完成: 导入sub…

    C 2023年5月22日
    00
  • windows中使用icacls命令还原文件夹的权限设置

    下面是详细讲解“windows中使用icacls命令还原文件夹的权限设置”的完整攻略。 一、什么是icacls命令 icacls命令是Windows系统中的一个命令行工具,它可以帮助我们管理文件和文件夹的访问控制列表(ACL)。ACL是指访问控制列表,用于控制文件和文件夹对用户或用户组的访问权限。 二、使用icacls命令还原文件夹的权限设置 当我们遇到Wi…

    C 2023年5月23日
    00
  • C++内存四区之代码区、全局区、栈区和堆区

    C++内存四区指的是程序在运行时所使用的内存分为代码区、全局区、栈区和堆区。下面我们分别来讲解一下这四个区域。 1. 代码区 代码区是存储函数体等二进制代码的区域,它需要保护,以免被其他程序或者用户修改。代码区一般位于内存的高地址部分,从而防止由于栈溢出操作而覆盖代码区。 代码示例: #include <iostream> int main() …

    C 2023年5月24日
    00
  • C++实现简单版通讯录管理系统

    C++实现简单版通讯录管理系统攻略 一、需求分析 通讯录是日常生活中广泛使用的一种记录联系人信息的工具。本次需求是实现一个简单的通讯录管理系统,主要包含如下功能: 添加联系人 显示所有联系人 查找联系人 删除联系人 修改联系人 根据以上需求,我们可以设计通讯录管理系统的主要数据结构是一个联系人类 Contact 类,包含姓名、手机、性别、等私有成员,以及相应…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部