服务器与客户端的一般套路

WinSocket 套接字

————服务器与客户端的一般套路

一、开发环境

  • IDE: Red Panda Dev-C++ 6.5
  • 编程语言:C语言
  • :winsock2.h

二、套接字工作流程图

img

注意:这个工作流程图非常重要,后面的代码编写基本就是这个逻辑

三、服务器各部分实现

  1. 导入头文件
    #include<stdio.h>
    #include<winsock2.h>	// 升级版头文件,现在一般都是用这个
    // #include<winsock.h>  // 原版头文件
    
  2. 初始化环境

    WSAStartup:在Windows平台上开发socket必写函数,用于允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节。只有调用了该函数window内核才知道你要使用的Socket API的版本号,所以一般都是放到代码之前,而且一般都是固定写法不需要改变。

    // 初始化 Socket环境 
    WSADATA WSAData;
    if(WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    	printf("初始化 Socket环境失败");
    	return -1;
    }
    	
    
  3. 创建套接字、绑定IP与端口,等待连接

    该步骤也基本是套路,只需要改下ip和端口就可以直接使用

    // 创建 Server 套接字
    SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == server) {
    	perror("创建 Server Socket失败!\n");
    	return -1;
    }
    
    // 创建并初始化服务器需要绑定IP和端口
    char IP[] = "127.0.0.1";
    int PORT = 8000;
    struct sockaddr_in server_addr;	// 服务器IP和端口信息
    server_addr.sin_family = AF_INET,	// 协议为网络协议
    server_addr.sin_port = htons(PORT),	// 绑定的端口
    // 绑定IP地址
    server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    // 服务器套接字绑定ip和端口
    int StatusCode = bind(server, (SOCKADDR*)&server_addr, sizeof(server_addr));
    if (SOCKET_ERROR == StatusCode) {
    	perror("Server Socket 绑定IP、端口失败\n");
    	return -1;
    }
    // 开始监听连接, 最多等待的连接数设置为10
    listen(server, 10);
    printf("Server 正在 %s %d 监听连接......\n", IP, PORT);
    
    
  4. 处理连接

    该部分基本也是套路,直接照搬

    // 接收客户端连接
    struct sockaddr_in client_addr;
    int client_addrlen = sizeof(client_addr);
    SOCKET client = accept(server, (SOCKADDR*)&client_addr, &client_addrlen);
    if (SOCKET_ERROR == client) {
    	perror("连接客户端失败\n");
    }
    
    
  5. 服务器与客户端交互

    该部分是交互部分,需要实现的具体功能就写到该部分,我这里的功能只是将客户端的数据原样返回

    // 处理客户端间的连接
    char buf[124] = {0};
    recv(client, buf, sizeof(buf), 0);	// 接收数据
    send(client, buf, sizeof(buf), 0);	// 发送数据
    
    
  6. 关闭连接
    // 关闭连接
    closesocket(client);
    closesocket(server);
    
  7. 释放套接字环境

    WSACleanup功能与WSAStartup功能相反

    // 释放资源
    WSACleanup();
    

如果在编译运行过程中报错,添加只需要在编译时添加上动态库(如下)

在这里插入图片描述

四、客户端各部分实现

  1. 导入头文件
    #include<stdio.h>
    #include<winsock2.h>	// 升级版头文件,现在一般都是用这个
    // #include<winsock.h>  // 原版头文件
    
    
  2. 初始化环境
    // 初始化 Socket环境 
    WSADATA WSAData;
    if(WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    	printf("初始化 Socket环境失败");
    	return -1;
    }
    
    
  3. 建立连接
    // 创建 Client 套接字
    SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (INVALID_SOCKET == client) {
    	perror("创建 Client Socket失败!\n");
    	return -1;
    }
    
    // 创建并初始化代表服务器地址的IP和端口
    char IP[] = "127.0.0.1";
    int PORT = 8000;
    struct sockaddr_in server_addr;	// 服务器IP和端口信息
    server_addr.sin_family = AF_INET,	// 协议为网络协议
    server_addr.sin_port = htons(PORT),	// 绑定的端口
    // 绑定IP地址
    server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    // 连接上面服务器地址信息指定的服务器
    connect(client, (SOCKADDR*)&server_addr, sizeof(server_addr));
    
    
  4. 与服务器进行交互
    // 处理客户端间的连接
    char buf[124] = {0};
    send(client, buf, sizeof(buf), 0);	// 发送数据
    recv(client, buf, sizeof(buf), 0);	// 接收数据
    printf("Client 接收到的数据为:%s\n", buf);
    
  5. 断块连接、释放环境
    // 关闭连接并释放资源
    closesocket(client);
    WSACleanup();
    
    

五、运行结果与源码

  1. 服务器
    #include<stdio.h>
    #include<winsock2.h>
    
    int main () {
    	// 初始化 Socket环境
    	WSADATA WSAData;
    	if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    		perror("初始化 Socket环境失败\n");
    		return -1;
    	}
    
    	// 创建 Server 套接字
    	SOCKET server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if (INVALID_SOCKET == server) {
    		perror("创建 Server Socket失败!\n");
    		return -1;
    	}
    
    	// 创建并初始化服务器需要绑定IP和端口
    	char IP[] = "127.0.0.1";	// 该ip代码的是本机地址
    	int PORT = 8000;
    	struct sockaddr_in server_addr;	// 服务器IP和端口信息
    	server_addr.sin_family = AF_INET,	// 协议为网络协议
    	server_addr.sin_port = htons(PORT),	// 绑定的端口
    	// 绑定IP地址
    	server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    	// 服务器套接字绑定ip和端口
    	int StatusCode = bind(server, (SOCKADDR*)&server_addr, sizeof(server_addr));
    	if (SOCKET_ERROR == StatusCode) {
    		perror("Server Socket 绑定IP、端口失败\n");
    		return -1;
    	}
    	// 开始监听连接, 最多等待的连接数设置为10
    	listen(server, 10);
    	printf("Server 正在 %s %d 监听连接......\n", IP, PORT);
    
    	// 接收客户端连接
    	struct sockaddr_in client_addr;
    	int client_addrlen = sizeof(client_addr);
    	SOCKET client = accept(server, (SOCKADDR*)&client_addr, &client_addrlen);
    	if (SOCKET_ERROR == client) {
    		perror("连接客户端失败\n");
    	}
    
    	// 处理客户端间的连接
    	char buf[124] = {0};
    	recv(client, buf, sizeof(buf), 0);	// 接收数据
    	send(client, buf, sizeof(buf), 0);	// 发送数据
    
    	// 关闭连接
    	closesocket(client);
    	closesocket(server);
    
    	// 释放资源
    	WSACleanup();
    	return 0;
    }
    
    
  2. 客户端
    #include<stdio.h>
    #include<winsock2.h>
    
    int main () {
    	// 初始化 Socket环境
    	WSADATA WSAData;
    	if (WSAStartup(MAKEWORD(2, 2), &WSAData) != 0) {
    		perror("初始化 Socket环境失败\n");
    		return -1;
    	}
    
    	// 创建 Client 套接字
    	SOCKET client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    	if (INVALID_SOCKET == client) {
    		perror("创建 Client Socket失败!\n");
    		return -1;
    	}
    
    	// 创建并初始化代表服务器地址的IP和端口
    	char IP[] = "127.0.0.1";
    	int PORT = 8000;
    	struct sockaddr_in server_addr;	// 服务器IP和端口信息
    	server_addr.sin_family = AF_INET,	// 协议为网络协议
    	server_addr.sin_port = htons(PORT),	// 绑定的端口
    	// 绑定IP地址
    	server_addr.sin_addr.S_un.S_addr = inet_addr(IP);
    
    	// 连接上面服务器地址信息指定的服务器
    	connect(client, (SOCKADDR*)&server_addr, sizeof(server_addr));
    
    	// 处理客户端间的连接
    	char buf[124] = {0};
    	send(client, buf, sizeof(buf), 0);	// 发送数据
    	recv(client, buf, sizeof(buf), 0);	// 接收数据
    	printf("Client 接收到的数据为:%s\n", buf);
    	
    	// 关闭连接并释放资源
    	closesocket(client);
    	WSACleanup();
    	return 0;
    }
    
    
  3. 运行结果

    在这里插入图片描述
    在这里插入图片描述

WinSocket常用函数介绍灰信网

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值