当前位置: 首页 > news >正文

Windows平台网络通信

参考文章:https://blog.csdn.net/only_write_bug/article/details/148590269?spm=1001.2014.3001.5502

一、环境配置

        我们使用Visual Studio 2008版本。

        1、导入头文件winsock2.h

        2、链接ws2_32.lib库

打开项目的属性页,选中“配置属性”-->"输入"—>“附加依赖项”。也可Alt+F7打开“属性页”。

在右边空白处填入ws2_32.lib。之后我们只需要在源文件中添加头文件winsock2.h即可。

二、Winsock的初始化

        进行Winsock编程时,首先调用WSAStartup函数,设置程序中要使用的Winsock版本。并初始化库。

#include <winsock2.h>int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSData);
//成功返回0,失败返回非0的错误码
//wVersionRequested:选中的Winsock版本信息
//lpWSData:WSADATA结构体变量的地址值
/*  wVersionRequested:若传递0x0201,表示主版本号1,副版本号2.   高八位为副版本号,低八位为主版本号。也可借助MAKEWORD宏函数构建版本信息MAKEWORD(1,2):主版本号1,副版本号2,返回0x0201.MAKEWORD(2,2):主版本号2,副版本号2,返回0x0202.
*///使用示例
int main()
{WSADATA wsaData;//定义WSADATA 结构体//调用初始化函数if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0){printf("WSAStartup error!\n");return 0;}return 0;
}

三、基于Windows的套接字相关函数       

#include <winsock2.h>SOCKET socket(int af, int type, int protocol);
/* 成功返回套接字句柄, 失败返回INVALID_SOCKET*/int bind(SOCKET s, const struct sockaddr*name, int namelen);
/* 与Linux系统的bind函数相同,实现IP和端口分配。 成功返回0, 失败返回SOCKET_ERROR*/int listen(SOCKET s, int backlog);
/* 与Linux系统的Listen函数相同,实现接收客户端连接功能, 成功返回0,失败返回SOCKET_ERROR*/SOCKET accept(SOCKET s, struct sockaddr*addr, int *addrLen);
/* 与Linux系统的accept函数相同,实现受理客户端连接请求,成功返回套接字句柄,失败返回INVALID_SOCKET*/int connect(SOCKET s, const struct sockaddr*addr, int addrLen);
/* 与Linux系统的connect函数相同, 实现从客户端发送连接请求的功能,成功返回0,失败返回SOCKET_ERROR */int closesocket(SOCKET s);
/*和Linux系统的close函数相同,实现关闭套接字连接,成功返回0,失败返回SOCKET_ERROR */int send(SOCKET s, const char*buf, int len, int flags);
/*成功返回0,失败返回SOCKET_ERROR */
/*s:传输数据的SOCKET套接字句柄buf:要传输的数据的地址值len:要传输的数据大小,字节数flags:传输数据时用到的多种选项,一般为 0 即可
*/int recv(SOCKET s, const char*buf, int len, int flags);
/*成功返回0,失败返回SOCKET_ERROR */
/*s:接收数据的SOCKET套接字句柄buf:要保存数据的地址值len:要接收的最大数据大小,字节数flags:接收数据时用到的多种选项,一般为 0 即可
*/

四、服务端与客户端创建示例

        一、Windows网络通信客户端创建示例

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>int main()
{char buff[100] = "hello, I am Client";char recvbuff[1024] = {0};//接收信息//1、初始化WSADATA结构体对象WSADATA wsaData;//2、初始化WSAStartupif(WSAStartup(MAKEWORD(2,2), &wsaData) != 0){printf("WSAStartup init error!\n");return 0;}//3、初始化套接字 TCP套接字SOCK_STREAM,PF_INET:IPV4互联网协议族SOCKET cli_socket;cli_socket = socket(PF_INET, SOCK_STREAM, 0);if(cli_socket == INVALID_SOCKET){printf("cli_socket init error!\n");return 0;}//4、初始化结构体SOCKADDR_IN ser_addr;//服务器IP和端口等信息memset(ser_addr, 0, sizeof(ser_addr));ser_addr.sin_family = AF_INET;ser_addr.sin_addr.s_addr = inet_addr("192.168.1.110");//指定服务器IPser_addr.sin_port = htons(8888);//指定服务器端口int ser_addrLen = sizeof(ser_addr);//5、与服务器建立连接if(connect(cli_socket, (SOCKADDR*)&ser_addr, ser_addrLen) == SOCKET_ERROR){printf("connect init error!\n");return 0;}//6、接收发送信息int recvlen = 0;    //接收字节长度//可添加循环退出标志  bool flag = true;while(1){//可添加循环判断/*if(!flag){break;}*/memset(recvbuff, 0, sizeof(recvbuff));//先清空recvlen = recv(cli_socket, recvbuff, sizeof(recvbuff)-1, 0);if(recvlen > 0){    printf("recvbuff is %s\n",recvbuff);//发送数据到服务器if(send(cli_socket, buff, sizeof(buff), 0) == SOCKET_ERROR){printf("socket send information error!\n");return 0;}//flag = false;}}closesocket(cli_socket);//关闭套接字WSACleanup();//清除WSAreturn 0;
}

        二、Windows网络通信服务端创建示例

#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>int main()
{char buff[100] = "hello, I am Server";char recvbuff[1024] = {0};//接收信息//1、初始化WSADATA结构体对象WSADATA wsaData;//2、初始化WSAStartupif(WSAStartup(MAKEWORD(2,2), &wsaData) != 0){printf("WSAStartup init error!\n");return 0;}//3、初始化套接字 TCP套接字SOCK_STREAM,PF_INET:IPV4互联网协议族SOCKET ser_socket;//服务器监听套接字ser_socket = socket(PF_INET, SOCK_STREAM, 0);if(ser_socket == INVALID_SOCKET){printf("ser_socket init error!\n");return 0;}//4、初始化结构体SOCKADDR_IN ser_addr;//服务器IP和端口等信息memset(&ser_addr, 0, sizeof(ser_addr));ser_addr.sin_family = AF_INET;ser_addr.sin_addr.s_addr = INADDR_ANY;//指定服务器IPser_addr.sin_port = htons(8888);//指定服务器端口int ser_addrLen = sizeof(ser_addr);//5、绑定自身端口和IP信息if(bind(ser_socket, (SOCKADDR*)&ser_addr, ser_addrLen) == SOCKET_ERROR){printf("bind init error!\n");return 0;}//6、监听连接对象if(listen(ser_socket, 5) == SOCKET_ERROR){printf("Listen init error!\n");return 0;}//7、接收连接请求建立连接SOCKET cli_socket;//客户端通信套接字SOCKADDR_IN cli_addr;//客户端IP和端口等信息int cli_addrLen = sizeof(cli_addr);cli_socket = accept(ser_socket, (SOCKADDR*)&cli_addr, &cli_addrLen);if(cli_socket == INVALID_SOCKET){printf("accept client error!\n");return 0;}//8、发送信息,接收信息send(cli_socket, buff, sizeof(buff), 0);int recvNum = 0;while(1){memset(recvbuff, 0, sizeof(recvbuff));recvNum = recv(cli_socket, recvbuff, sizeof(recvbuff)-1, 0);if(recvNum > 0){    printf("recvbuff is %s\n",recvbuff);// 添加退出条件示例if(strcmp(recvbuff, "exit") == 0) break;}    }closesocket(cli_socket);//关闭套接字closesocket(ser_socket);//关闭套接字WSACleanup();//清除WSAreturn 0;
}

        三、服务器部分添加多线程实现

// 使用多线程或select()处理多个客户端
while(1) {SOCKET new_client = accept(...);CreateThread(NULL, 0, ClientHandler, (LPVOID)new_client, 0, NULL);
}

http://www.xdnf.cn/news/987751.html

相关文章:

  • SQL Server 查询数据库中所有表中所有字段的数据类型及长度
  • 从“字对字“到“意对意“:AI翻译正在重塑人类的语言认知模式
  • 从代码学习深度学习 - 全局向量的词嵌入(GloVe)PyTorch版
  • 医疗行业双碳战略升维:从合规达标到价值创造的转型路径
  • JavaWeb(JavaBean预习)
  • 智慧园区智能化整体解决方案
  • c#实现绝对路径和相对路径的转换
  • 黑马python(四)
  • CentOS Stream 9——RustDesk基础版自建教程(Docker)
  • <script> 标签的 async 与 defer 属性详解
  • 《Linux C编程实战》笔记番外:如何避免子进程成为僵尸进程
  • 阿里云unbantu、Flask部署模型的一个错误
  • 安卓+苹果端签名教程
  • SiteAzure:文章删除后,前台还能搜索到
  • HarmonyOS - UIObserver(无感监听)
  • TF-IDF算法的代码实践应用——关键词提取、文本分类、信息检索
  • 帆软 BI 从入门到实战全攻略(一):安装激活与添加数据
  • 大量RPM仓库管理指南:更新与批量获取实战手册
  • VS2017----打开ui文件几秒后闪退
  • 汇编(函数调用)
  • 刷新网站 favicon 的几种方法
  • 医院重症监护系统 ICU重症病房管理系统 重症监护软件
  • QT第一课 —— 设置CMake路径
  • Rust:在Windows上安装
  • BEV和OCC学习-7:mmdet3d 3D检测demo测试
  • 剑指offer21——反转链表
  • 使用html写一个倒计时页面
  • 将模型保存到kaggle中的model中
  • 解码 K-Means 聚类:开启数据星河的炫酷聚类新纪元
  • 前端项目主题切换