使用Socket API建立简易的TCP服务端

目录

  • 建立一个socket

  • 绑定接受客户端连接的端口bind

  • 监听网络端口listen

  • 等待接受客户端连接accept

  • 向客户端发送一条数据send

  • 关闭socket

  • 代码展示

建立一个socket

  • 使用socket函数返回SOCKET 对象

    • 返回值:设置完成的SOCKET对象

    • 参数1:IP协议类型

      • [AF_INET]  IPV4

      • [AF_INET6]  IPV6

    • 参数2:传输的数据报类型

      • [SOCK_STREAM]  流格式SOCKET

        流格式套接字(Stream Sockets)也叫“面向连接的套接字”,在代码中使用 SOCK_STREAM 表示。

        SOCK_STREAM 是一种可靠的、双向的通信数据流,数据可以准确无误地到达另一台计算机,如果损坏或丢失,则会重新发送。

        流格式套接字有自己的纠错机制,在此我们就不讨论了。

        SOCK_STREAM 有以下几个特征:

        • 数据在传输过程中不会消失;

        • 数据是按照顺序传输的;

        • 数据的发送和接收不是同步的(不存在数据边界)

        • 基于TCP协议

      • [SOCK_DGRAM]  数据报格式SOCKET

        数据报格式套接字(Datagram Sockets)也叫“无连接的套接字”,在代码中使用 SOCK_DGRAM 表示。

        计算机只管传输数据,不作数据校验,如果数据在传输中损坏,或者没有到达另一台计算机,是没有办法补救的。也就是说,数据错了就错了,无法重传。

        因为数据报套接字所做的校验工作少,所以在传输效率方面比流格式套接字要高。

        可以将 SOCK_DGRAM 比喻成高速移动的摩托车快递,它有以下特征:

        • 强调快速传输而非传输顺序;

        • 传输的数据可能丢失也可能损毁;

        • 限制每次传输的数据大小;

        • 数据的发送和接收是同步的(存在数据边界)

        • 基于UDP协议

    • 参数3:传输协议

      • [IPPROTO_TCP]  TCP协议

      • [IPPROTO_UDP]  UDP协议

绑定接受客户端连接的端口bind

  • 使用bind函数连接客服端的IP地址及端口

    • 返回值:绑定结果的状态

      失败返回0,但是一般为了代码的可读性,使用给定的宏 SOCKET_ERROR

    • 参数1:SOCKET接口

      填入上一步使用socket函数返回的SOCKET对象即可

    • 参数2:可被绑定的端口

      使用sockaddr_in创建可被绑定的地址对象

      • 设置端口协议: (创建的对象名).sin_family = 上一步选择的IP协议类型

      • 分 配 端 口 号:(创建的对象名).sin_port = htons(设定的端口号)

      htons:

      端口号在传输过程中为2字节的unsigned short类型

      网络传输中的short类型经过特殊处理,与内置的类型不同,则需要htons函数进行转换

      htons = host to net unsigned short

      • 设定IP地址:(创建的对象名).sin_addr.S.un.S.addr = (设定的IP)

      其中“127.0.0.1”意味着本地主机的地址,一般用于本地测试

      同时windows提供了宏定义 INADDR_ANY,表示使用主机任意IP地址

监听网络端口listen

  • 使用listen函数监听网络端口

    • 返回值:监听状态

      同bind函数一样,建议使用SOCKET_ERROR判断监听结果

    • 参数1:SOCKET接口

      填入第一步使用socket函数返回的SOCKET对象即可

    • 参数2:backlog

      这个参数涉及到一些网络的细节。进程处理一个一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接,这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。

      毫无疑问,服务器进程不能随便指定一个数值,内核有一个许可的范围。这个范围是实现相关的。很难有某种统一,一般这个值会小30以内

等待接受客户端连接accept

  • 使用accept函数接收客户端的请求

    • 返回值:新建立的客户端对象(仍属于发送端)

      如果失败,会返回一个INVALID_SOCKET对象

      可以使用通过查看返回对象内的sin_addr成员,来读取客户端ip地址

      同端口设置一样,需要使用转换函数inet_ntoa([接收的对象名].sin_addr)转换成字符串类型

      该函数在vs中已经被弃用

      第一行中添加宏定义#define _WINSOCK_DEPRECATED_NO_WARNINGS可消除警告

    • 参数1:SOCKET接口

    • 参数2:用于存放请求的客户端的地址

      传入一个新的SOCKET地址对象(建议初始化为空)

    • 参数3:客户端的大小

      使用sizeof(客服端的类型),需要传入int*的变量

向客户端发送一条数据send

  • 使用send函数向客户端返回数据

    • 返回值

    • 参数1:客户端的SOCKET对象

      accpet函数接收返回的SOCKET对象

    • 参数2:传送的数据(const char*类型)

    • 参数3:传送的数据的大小

    • 参数4:默认值填0

关闭socket

  • 使用closesocket关闭创建的socket

    • 参数1:第一步创建的SOCKET对象


代码展示

#define _WINSOCK_DEPRECATED_NO_WARNINGS
​
#include <WinSock2.h>
#include <windows.h>
#include <iostream>
​
using std::cout;
using std::endl;
​
#pragma comment(lib, "ws2_32.lib")
//#define _WINSOCK_DEPRECATED_NO_WARNINGS
​
​
int main() {WORD ver = MAKEWORD(2, 2);WSADATA wsa;WSAStartup(ver, &wsa);//建立一个socket接口SOCKET _sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//使用bind绑定接受客户端连接的网络端口sockaddr_in _sin = {};_sin.sin_family = AF_INET;_sin.sin_port = htons(4567);                //host to net unsigned short_sin.sin_addr.S_un.S_addr = INADDR_ANY;     //inet_addr("127.0.0.1");if (SOCKET_ERROR == bind(_sock, (sockaddr*)&_sin, sizeof(_sin))) {cout << "绑定失败" << endl;}else {cout << "绑定成功!" << endl;}
​//使用listen监听网络端口const int maxLinkNum = 5;if (SOCKET_ERROR == listen(_sock, maxLinkNum)) {cout << "监听失败" << endl;}else {cout << "监听成功!" << endl;}
​//accept等待客户端进行链接SOCKADDR_IN cAddr = {};int cAddrLen = sizeof(SOCKADDR_IN);SOCKET _cSock = INVALID_SOCKET;char msg[] = "Hello Socket!";
​while (true) {_cSock = accept(_sock, (SOCKADDR*)&cAddr, &cAddrLen);if (_cSock == INVALID_SOCKET) {cout << "接受的地址无效" << endl;}cout << "新客户端加入:IP = " << inet_ntoa(cAddr.sin_addr) << endl;//send向客户端返回数据send(_cSock, msg, strlen(msg) + 1, 0);}
​//关闭socketclosesocket(_sock);
​WSACleanup();return 0;
}

C++使用socket的api创建简单服务器相关推荐

  1. 使用Socket及ServerSocket创建简单的服务器

    使用Socket及ServerSocket创建简单的服务器 @(JAVA)[java] 参考自core java package com.lujinhong.corejava;import java. ...

  2. dingo php,用laravel dingo/api创建简单的api

    这篇文章主要介绍了关于用laravel dingo/api创建简单的api,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下 1,修改.env配置文件添加API_STANDARDS_TRE ...

  3. 使用node创建简单服务器

    1.创建文件夹,并使用vscode打开 2.控制台输入如下命令,使其变为一个合法包: npm init 3.输入名字回车后,后面可不配置,一路回车就可 4.控制台输入如下,安装express npm ...

  4. 【API进阶之路】因为不会创建云服务器,我被实习生摆了一道

    事情是这样的,公司成立了一个新项目,要给项目建官网,并搭建一个web服务器.按照我的习惯,搭建一个本地虚拟机就好了,部署简单方便还好配置,云服务器嘛,写了10年代码,还是不习惯那玩意儿. 我这刚开始动 ...

  5. python应用系列教程——python使用socket创建tcp服务器和客户端

    全栈工程师开发手册 (作者:栾鹏) python教程全解 python使用socket创建tcp服务器和客户端. 服务器端为一个时间戳服务器,在接收到客户端发来的数据后,自动回复. 客户端,等待用户输 ...

  6. 基于Python Tkiner、thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信

    基于Python Tkiner.thread与socket实现的简单多人聊天室,在Python中创建TCP服务器与客户端进行通信 完整代码下载地址:基于Python Tkiner.thread与soc ...

  7. node aws 内存溢出_如何使用Node.js和AWS快速创建无服务器RESTful API

    node aws 内存溢出 by Mark Hopson 马克·霍普森(Mark Hopson) 如何使用Node.js和AWS快速创建无服务器RESTful API (How to quickly ...

  8. JAVA编写的一个简单的Socket实现的HTTP响应服务器

    JAVA编写的一个简单的Socket实现的HTTP响应服务器,看后就很容易理解Web服务器的原理了. package test.io;import java.net.*; import java.io ...

  9. python 搭建的http 动态服务器_Python 创建HTTP服务器的简单示例

    这篇文章主要为大家详细介绍了Python 创建HTTP服务器的简单示例,具有一定的参考价值,可以用来参考一下. 对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! ...

最新文章

  1. 2022年3月14日蓝桥杯基础算法能力测试
  2. linux集群管理权限,Linux下ACL权限管理
  3. NYOJ 27 大数阶乘
  4. android高级资料
  5. 算法:还有比二分查找更快的算法,判断是否是子字符串Is Subsequence
  6. 基于SSM的高校学生实习管理系统
  7. sketchup生成面域插件_什么插件这么神奇,SketchUp一秒搞定99%异形建模
  8. Python自动化办公之PDF拆分
  9. 【题解】食物链(并查集)
  10. 有计划,坚决执行——写给大三犹豫的女生
  11. docker镜像迁移mysql启动报错_README.md
  12. 设计思维——科学提升创造力的方法
  13. 企业级前端项目组框架vue-fpg介绍
  14. Facebook 新品 Lexical, 比 Quill 更好用的 Editor ?
  15. 计算机一级考试wps应用题库,一级计算机基础及WPS Office应用考前练习题
  16. 公共关系礼仪实务章节测试题——公共关系概述(四)
  17. WOL开启远程唤醒开机功能笔记
  18. 什么是720°全景照片?如何制作720全景图
  19. RoadFlow ASP.NET Core工作流引擎IIS部署
  20. 旧上海黑社会老大杜月笙的经典语录,有些道理

热门文章

  1. 【VSCode】Could not establish connection The VS Code Server failed to start的三种原因和三种解决方案
  2. 2019亚洲北京新零售展览会-展会新闻资讯
  3. 现学现卖做一个炫酷的动态背景页面
  4. 中级软考-软件设计师(二)
  5. 智能手表打破“寡头效应”,国产品牌能否再创手机神话?
  6. rabbitmq-server-3.8.9-1.el7.noarch.rpm百度网盘链接
  7. Docker自动部署Apache Tomcat
  8. WebService学习教程(一)
  9. MATLAB中eps使用
  10. word/excel/cad中插入二维码