相关视频——C3程序猿-windows网络编程:第一部分tcp/ip

我的小站——半生瓜のblog


基于TCP/IP协议的C/S模型

  • 基于TCP/IP协议的C/S模型
    • TCP/IP协议
    • Client/Server客户端/服务器模型
    • 套接字编程与socket编程
    • 使用
    • 服务端
      • 网络头文件&网络库
      • 打开网络库
        • 参数1
        • 参数2
        • 返回值
      • 校验版本
      • 创建socket
        • 什么是socket
        • 意义
        • 本质
        • 应用
        • 参数1
        • 参数2
        • 参数3
        • 返回值
      • 绑定地址与端口
        • 作用
        • 参数1
        • 参数2
        • 返回值
      • 开始监听
        • 作用
        • 参数1
        • 参数2
        • WSAAPI
        • 返回值
      • 创建客户端socket/接收连接
        • 作用
        • 参数1
        • 参数2
        • 参数3
        • 返回值
        • accept调试
      • 与客户端收发消息
          • 原理
          • 参数1
          • 参数2
          • 参数3
          • 参数4
          • 返回值
          • 作用
          • 参数1
          • 参数2
          • 参数3
          • 参数4
          • 返回值
      • 完整代码
    • 客户端
      • 链接到服务器
        • 作用
        • 参数1
        • 参数2
        • 参数3
        • 返回值
      • 完整代码
    • 延伸

基于TCP/IP协议的C/S模型

TCP/IP协议

全称——Transmission Control Protocol / Internet Protocol

重要性——TCP/IP协议是今天互联网的基石,没有这个就上不了网

概念——TCP/IP协议族(簇,组,体系),并不是TCP协议和IP协议的总称,指的是整个网络传输体系。而TCP协议和IP协议就是单单的两个协议。

特点——面向可连接的,可靠的,基于数据报的传输协议层


UDP/IP协议——面向非连接的,不可靠的,基于数据报的传输层协议。


Client/Server客户端/服务器模型

C/S模型其实是概念层面的,实现层面可以是基于任何的网络协议。

常见的还有B/S模型——浏览器/服务器模型,基于http/https协议的

套接字编程与socket编程

socket中文——套接字

统称网络编程

使用

  • 局域网
  • 广域网——内网穿透,内网转发

服务端

网络头文件&网络库

是最底层的网络函数,QT、MFC、WPF等封装好的网络库都是对这些最本质的网络函数的二次封装。

不区分大小写(windows)

#include<WinSock2.h>
//第二版的网络库,是一版的升级优化版本
#pragma comment(lib,"ws2_32.lib")
//.lib静态库后缀,是库文件,将.cpp文件编译为二进制文件
//好处:使用时无需编译,直接使用,解决时间
//32位编译环境和64位编译环境都用这个,没有ws2_64

打开网络库

功能

打开网络库/启动网络库,启动了这个库,库里的函数才能使用,功能才能实现。

int WSAStarp(
WORD wVersionRequired,
LPWSADATA lpWSAData
);

参数1

参数1-使用哪个版本的网络库-WORD-无符号shortWORD wdVersion = MAKEWORD(2, 1);
//主版本号2存在低数据位,副版本号1存在高数据位

参数前面有lp传地址


参数2

参数2-创建一个结构体,传递给系统,系统将信息放到结构体中,函数调用之后在外面通过结构体查看系统传递给我们的信息。
********************************************************************************WSADATA wdSockMsg;
********************************************************************************
其中包括struct WSAData {WORD                    wVersion;//我们要使用的版本WORD                    wHighVersion;//系统能提供给我们的最高的版本unsigned short          iMaxSockets;//返回可用的socket数量,2版本之后就没用了unsigned short          iMaxUdpDg;//UDP数据报信息的大小,2版本之后就没用了char FAR *              lpVendorInfo;//供应上特定的信息,2版本呢之后就没用 了char                    szDescription[WSADESCRIPTION_LEN+1];//当前库的描述信息,2.0是第二版的意思char                    szSystemStatus[WSASYS_STATUS_LEN+1];char                    szDescription[WSADESCRIPTION_LEN+1];char                    szSystemStatus[WSASYS_STATUS_LEN+1];}
****************************************************************************************************************************************************************WSAStartup(wdVersion,&wdSockMsg);
********************************************************************************
当输入的版本不存在例如:1.3 2.3——有主版本,没有副版本 得到主版本的的最大副版本 1.1 2.2并使用3.1 3.3——超过最大版 本号,使用系统能提供的最大版本2.20.0 0.1 0.3——主版本是0,不支持请求的套接字版本

返回值

每一种错误有它唯一的对应码

if (nRes != 0){printf("网络库打开失败");return 0;}返回值-成功返回0-失败返回对应错误的宏WSASYSNOTREADY   10091 底层网络子系统尚未准备好进行网络通信。                              系统配置问题,重启下电脑,检查ws2_32库是否存在,或者是否在环境配置目录下WSAVERNOTSUPPORTED 10092 此特定Windows套接字实现不提供所请求的Windows套接字支持版本。      要使用的版本不支持WSAEPROCLIM     10067  已达到对Windows套接字实现支持的任务数量的限制。Windows Sockets实现可能限制同时使用它的应用程序的数量WSAEINPROGRESS    10036          正在阻止Windows Sockets 1.1操作。                                                 当前函数运行期间,由于某些原因造成阻塞,会返回在这个错误码,其他操作均禁止WSAEFAULT       10014          lpWSAData参数不是有效指针。                                                     参数写错了

校验版本

HIBYTE(wdSockMsg.wVersion) != 2 || LOBYTE(wdSockMsg.wVersion) != 2HIBYTE是高位-副版本LOBYTE是低位-主版本例如:只要有一个不是2,说明系统不支持我们要的2.2版本前面为主版本,后面为副版本要打开2.1
HIBYTE(wdSockMsg.wVersion) != 1 && LOBYTE(wdSockMsg.wVersion) != 2如果版本不对WSACleanup();//清理网络库return 0;

创建socket

SOCKET socket(int af,int type,int protocol
);

例如

SOCKET socketServer = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

什么是socket

将底层复杂的协议体系,执行流程,进行封装,封装完的结果,就是一个socket了。

也就是说,socket是我们调用协议进行通信的操作接口。

意义

将复杂的协议过程与编程人员分开,我们只需要操作一个简单那的SOCKET就行了,对于底层的协议过程细节,我们完全不用知道,这就大大的方便了我们。

网络编程难在协议本身的复杂性,简单在我们编程层面完全不用考虑哪些。

本质

就是一种数据类型。就是一个整数。

socket的值是唯一的,通过这个值找到对应的协议。

应用

网络通信的函数,全都要使用SOCKET,每个客户端有一个SOCKET,服务器有一个SOCKET,通信的时候,就需要这个SOCKET做参数,跟谁通信,就要传递谁的SOCKET。

SOCKET是网络封装的精华,写代码就是不停的使用SOCKET这个变量,所以又叫SOCKET编程。

参数1

地址的类型

加入你要与好友取得联系,可以通过    电话、QQ、微信等方式
AF_INET 2ipv4地址Internet协议版本地址系列例如:192.168.1.1030.0.0.0~255.255.255.2554字节,32位的地址点分十进制表示法
AF_INET6 23ipv6地址Internet协议版本地址系列例如:2001:0:3238:DFE1:63::FEFB16字节,128位地址
AF_BTH 32    蓝牙地址    例如:6B:2D:BC:A9:8C:12
AF_IRDA 26    红外数据协会(lrDA)地址

参数2

套接字类型

SOCK_STREAM 1提供给带有OOB数据传输机制的顺序,可靠,双向,基于连接的字节流。使用TCP作为internet地址系列AF_INET or AF_INET6
SOCK_DGRAM 2固定(通常很小)最大长度的无连接,不可靠的缓冲区。使用UDP作为internet地址系列AF_INET or AF_INET6
SOCK_RAW 3提供允许应用程序操作下一个上层协议头的原始套接字。 要操作IPv4标头,必须在套接字上设置IP_HDRINCL套接字选项。要操作IPv6标头,必须在套接字上设置IPV6_HDRINCL套接字选项。
SOCK_RDM 4    提供可靠的消息数据报。
这种类型的一个示例是Windows中的实用通用多播(PGM)多播协议实现,通常称为可靠多播节目。
仅在安装了可靠多播协议时才支持此类型值。
SOCK_SEQPACKET 5    提供基于数据报的伪流数据包。

参数3

协议类型

这个位置写0是什么意思?   即系统给我们自动选择合适的协议。但不明确。
IPPROTO_TCP传输控制协议(TCP)。 当af参数为AF_INET或AF_INET6且类型参数为SOCK_STREAM时,这是一个可能的值。可能的值是什么意思?如果有个协议TOP前两个参数也传这样的参数,此时(socket)第三个参数即写成IPPROTO_TOP
IPPROTO_UDP
用户数据报协议(UDP)。 当af参数为AF_INET或AF_INET6且类型参数为SOCK_DGRAM时,这是一个可能的值。
IPPROTO_ICMP   Internet控制消息协议(ICMP)。 当af参数为AF_UNSPEC,AF_INET或AF_INET6且类型参数为SOCK_RAW或未指定时,这是一个可能的值。
IPPROTO_IGMP
Internet组管理协议(IGMP)。
当af参数为AF_UNSPEC,AF_INET或AF_INET6且类型参数为SOCK_RAW或未指定时,这是一个可能的值。
IPPROTO_RM
用于可靠多播的PGM协议。
当af参数为AF_INET且类型参数为SOCK_RDM时,这是一个可能的值。
在针对Windows Vista及更高版本发布的Windows SDK上,此协议也称为IPPROTO_PGM。
仅在安装了可靠多播协议时才支持此协议值。

返回值

成功-返回可用的socket
失败-不用了一定要释放掉——closesocket(xxx);然后再WSACleanup();清理网络库注意二者的先后顺序,一定要先释放,然后再清理网路库,因为closesocket()是网络库中的函数。
********************************************************************************
失败——返回INVALID_SOCKETif (INVALID_SOCKET == socketServer){int a = WSAGetLastError();//获取错误码WSACleanup();return 0;}//获取错误码——int a = WSAGetLastError();//检测在它上面离它最近的错误码    

绑定地址与端口

int bind(    SOCKET s,   const sockaddr* addr,   int namelen);

作用

给我们的socket绑定端口号和具体地址

地址:找到电脑,理论上只有一个。

端口号:找到电脑上对应软件的具体功能,每个通信的端口号是唯一的,同一个软件可能占用多个端口号。

参数1

传递上面创建好的socket

(scoket绑定好地址类型、socket类型,协议类型)

(bind绑定实质的地址、端口号)

参数2

struct sockaddr {ushort  sa_family;//地址类型char    sa_data[14];//端口号 ip地址//往一个字符串中赋值端口号和ip地址不好赋所以给出sockaddr_in,与之对应
};//16个字节struct sockaddr_in {short   sin_family;//地址类型u_short sin_port;//端口号struct  in_addr sin_addr;//ip地址,4字节char    sin_zero[8];
};//16字节
//两个结构体大小和内存排布一样
结构体-地址类型-ip地址    127.0.0.1-回送地址 本地回环地址 本地网络测试192.168.xxx.xxx- 用户ip地址-端口号  就是一个整数,0~65535。unsigned short理论上0~65535都可以,但是0~1023为系统保留占用端口号21端口分配给FTP(文件传输协议)服务25端口分配给SMTP(简单邮件传输协议)服务80端口分配给HTTP服务所以真正的范围是1024~65535端口是唯一的。打开cmd,输入netstat -ano 查看被使用的所有端口netstat -aon|findstr "12345"检查我们要使用的端口是否被占用SOCKETADDR_IN为sockaddr提供方便
创建一个结构体SOCKETADDR_IN
为其中的结构体成员赋值
然后将它强转成sockaddr添加成功SOCKADDR_IN si;si.sin_family = AF_INET;//地址类型si.sin_port = htons(12345);//端口-将输入的unsigned short转换si.sin_addr.S_un.S_addr = inet_addr("127,0,0,1");//ip地址bind(socketServer, (const struct sockaddr*)&si, sizeof(si));

返回值

成功-返回0
失败-失败 返回宏SOCKET_ERROR具体错误码通过WSAGetLastError()获得if (SOCKET_ERROR == bind(socketServer, (const struct sockaddr*)&si, sizeof(si)))
{int a = WSAGetLastError();    //释放closesocket(socketServer);//关闭网络库WSACleanup();return 0;
}

开始监听

int WSAAPI listen(   SOCKET s,   int backing);
listen(socketServer, SOMAXCONN);

作用

将套接字置于正在侦听传入连接的状态。

参数1

服务器端的socket,也就是socket函数创建的。

参数2

挂起连接的最大长度。(排队等待区)休息区的长度。

可以手动设置,可能是2~10,一般是SOMAXCONN让系统自己选择最合适的个数。不同系统的环境不一样,所以这个合适的数也都不一样。

WSAAPI

调用约定,是给操作系统看的,我们可以忽略它。

决定-函数名字的编译方式-参数的入栈顺序-函数的调用时间。

返回值

成功-返回0
失败-返回宏SOCKET_ERRORif (SOCKET_ERROR == listen(socketServer, SOMAXCONN)){//出错了int a = WSAGetLastError();//释放closesocket(socketServer);//关闭网络库WSACleanup();return 0;}

创建客户端socket/接收连接

将每个客户端的信息都创建成一个socket。

SOCKET WSAAPI accept(SOCKET s,sockaddr * addr,int *addrlen
);

作用

accept函数允许在套接字上进行传入连接尝试。

listen监听客户端来的链接,accept将客户端的信息绑定到一个socket上,也就是给客户端创建一个socket,通过返回值得到客户端socket。

一次只能创建一个(返回值1个),有几个客户端链接,就要调用几次。

参数1

(服务器socket)

参数2

客户端的地址端口信息结构体,同bind的第二个参数

意义:系统帮我们监视着客户端的动态,肯定会记录客户端的信息,也就是IP地址,和端口号,并通过这个结构体记录。

只是这个我们不用自己填写结构体中的内容,系统帮我们填写

 //创建客户端struct sockaddr_in clientMsg;//客户端信息int len = 0;SOCKET socketClient = accept(socketServer, (struct sockaddr*)&clientMsg, &len);

参数3

参数2的大小


参数2、3也可以都写成NULL,那就是不直接得到客户端的地址、端口号。

可以通过getpeername(newSocket, (struct sockaddr*)&sockClient, &nLen);
得到客户端信息通过getsockname(sSocket, (sockaddr*)&addr, &nLen);
得到本地服务器信息

返回值

成功-返回客户端socket
失败-INVALID_SOCKETif (socketClient == INVALID_SOCKET){closesocket(socketServer);closesocket(socketClient);WSACleanup();//清理网络库return 0;}

accept调试

1.阻塞,同步,当服务器没有客户端链接时,它会一直等待。

2.多个链接,一次只能连接一个,5个就要循环5次。同时客户端socket也要创建成数组,否则上一个的socket就丢了。

与客户端收发消息

消息从谁那来,要发送给谁,就写谁的socket

得到指定客户端(参数1)发来的消息

int recv(SOCKET s,char *buf,//消息,按字节int len,//长度int flags
);
例:char buf[1500] = { 0 };int res = recv(socketClient, buf, 1499, 0);
原理

本质就是复制。

数据的接收都是由协议本身做的,也就是socket的底层做的,系统会有一段缓冲区,存储着收到的数据。

recv的作用就是通过socket找到这个缓冲区,并把数据赋值进参数2。

参数1

客户端的socket,每个客户端对应唯一的socket

参数2

客户端消息的存储空间,是个字符数组,一般是1500字节。

网络传输的最大单元是1500字节,也就是客户端发过来的数据,一次最大就是1500字节,这是协议规定,很多情况总结出来的最优值。

参数3

想要读取的字节个数。

一般是参数2的字节数-1,把/0字符串结尾留出来。

参数4

数据的读取方式

一般就写个0。

0
正常逻辑(自然性质)从系统缓冲区里读,读走几个删几个,要不每次都从头开始读。
MSG_PEEK读完不删不建议使用
MSG_OOB带外数据就是传输一段数据,在外带一个额外的特殊数据。(小声bb)不建议使用,读数据不行,无法计数。
NSG_WAITALL      直到系统缓冲区字节数满足参数3所请求的字节数,才开始读取。
返回值
返回读出来字节大小,读没了就在recv函数卡着,等着客户端发来数据,即阻塞,同步。死等
客户端下线,返回0。
执行失败,返回SOCKET_ERROR    if (res == 0)//客户端下线,链接中断{printf("链接中断、客户端下线\n");}else if (res == SOCKET_ERROR){printf("出错了\n");int a = WSAGetLastError();//根据实际情况处理}else{printf("%d  %s\n", res, buf);} 

int WSAAPI send( SOCKET s,   const char* buf,    int len,    int flags);
作用

向目标发送数据

本质:send函数将我们的数据复制粘贴进系统的协议发送缓冲区,计算机伺机发出去。

传输单元是1500字节。

参数1

目标的socket,每个客户端对应唯一的socket

参数2

给对方发送的字节串。1500

这个大小不同的协议不一样,
链路层14字节,ip头20字节,tcp头20字节,数据结尾还要有状态确认,加起来也几十个字节,
数据结尾还要要状态确认,加起来也几十个字节,所以实际的数据位,不能写1500个,要留出来,
例如1024,或者最多写1400,别多于1400是最好的。
超过1500系统会分片处理,比如2000个字节系统分成两个包,1400+包头 == 1500 假设包头100字节600+包头 == 700分两次发送出去结果系统要分包再打包,再发送,客户端收到之后还得拆包,组合数据,从而增加了系统的工作,降低了效率。有的协议,就把分片后的二包直接丢了。
参数3

字节个数。1400

参数4
0
MSG_OOB 同recv
MSG_DIBTROUTE指定数据不应受路由限制,Windows套接字服务提供程序可以选择忽略此标志。
返回值
成功-返回写入的字节数
失败-返回SOCKET_ERRORWSAGetLastError()得到错误码根据错误码信息做相应处理-重启-等待-不用理会

完整代码

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<WinSock2.h>
#include<stdio.h>
#include<string.h>
#pragma comment(lib,"ws2_32.lib")int main(void)
{//打开网络库 WORD wdVersion = MAKEWORD(2, 2);WSADATA wdSockMsg;int nRes = WSAStartup(wdVersion,&wdSockMsg);if (nRes != 0){printf("网络库打开失败");return 0;}//校验版本if (HIBYTE(wdSockMsg.wVersion) != 2 || LOBYTE(wdSockMsg.wVersion) != 2){//说明版本不对printf("版本不对");WSACleanup();//清理网络库return 0;}//创建socketSOCKET socketServer = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);if (INVALID_SOCKET == socketServer){printf("创建服务器socket失败");int a = WSAGetLastError();//获取错误码WSACleanup();return 0;}SOCKADDR_IN si;si.sin_family = AF_INET;//地址类型si.sin_port = htons(12345);//端口-将输入的unsigned short转换si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//ip地址if (SOCKET_ERROR == bind(socketServer, (const struct sockaddr *)&si, sizeof(si))){printf("绑定错误");int a = WSAGetLastError();//释放closesocket(socketServer);//关闭网络库WSACleanup();return 0;}//开始监听if (SOCKET_ERROR == listen(socketServer, SOMAXCONN)){//出错了int a = WSAGetLastError();//释放closesocket(socketServer);//关闭网络库WSACleanup();return 0;}//创建客户端struct sockaddr_in clientMsg;//客户端信息int len = sizeof(clientMsg);SOCKET socketClient = accept(socketServer, (struct sockaddr*)&clientMsg, &len);if (socketClient == INVALID_SOCKET){printf("客户端链接失败");closesocket(socketServer);closesocket(socketClient);WSACleanup();//清理网络库return 0;}printf("客户端链接成功\n");//收发消息int sValue = send(socketClient, "服务器链接成功", sizeof("服务器链接成功"), 0);if (sValue == SOCKET_ERROR){int a = WSAGetLastError();closesocket(socketClient);closesocket(socketServer);WSACleanup();return 0;}while (1){char buf[1500] = { 0 };int res = recv(socketClient, buf, 50, 0);if (res == 0)//客户端下线,链接中断{printf("链接中断、客户端下线\n");}else if (res == SOCKET_ERROR){printf("出错了\n");int a = WSAGetLastError();//根据实际情况处理}else{printf("客户端说:    %d  %s\n", res, buf);}scanf("%s", buf);send(socketClient, buf,strlen(buf), 0);}closesocket(socketServer);closesocket(socketClient);WSACleanup();//清理网络库system("pause");return 0;
}

客户端

网络库头文件 网络库打开网络库校验版本创建SOCKET

链接到服务器

int WSAAPI connect(SOCKET s,const sockaddr* name,int namelen
);
struct sockaddr_in serverMsg;
serverMsg.sin_family = AF_INET;
serverMsg.sin_port = htons(12345);//转换成网络字节序
serverMsg.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//服务器ip地址connect(socketServer, (struct sockaddr*)&serverMsg, sizeof(serverMsg));

作用

链接服务器并把服务器socket绑定到一起。

参数1

服务器socket

参数2

服务器ip地址端口号结构体

参数3

参数2结构体大小

返回值

成功-返回0
失败-返回SOCKET_ERROR

客户端与服务器收发消息,一发一接,一发一接,对应。


完整代码

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<WinSock2.h>
#pragma  comment(lib,"Ws2_32.lib")
int main(void)
{WORD wdVersion = MAKEWORD(2, 2);WSADATA wdSockMsg;int nRes = WSAStartup(wdVersion, &wdSockMsg);if (nRes != 0){printf("网络库打开失败");return 0;}//校验版本if (HIBYTE(wdSockMsg.wVersion) != 2 || LOBYTE(wdSockMsg.wVersion) != 2){//说明版本不对printf("版本不对");WSACleanup();//清理网络库return 0;}//创建的是服务器的,客户端不用创建自己的socket,因为链接服务器,服务器会创建出来客户端的socketSOCKET socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if (INVALID_SOCKET == socketServer){int a = WSAGetLastError();WSACleanup();return 0;}//链接服务器struct sockaddr_in serverMsg;serverMsg.sin_family = AF_INET;serverMsg.sin_port = htons(12345);//转换成网络字节序serverMsg.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//服务器ip地址int cValue = connect(socketServer, (struct sockaddr*)&serverMsg, sizeof(serverMsg));if (cValue == SOCKET_ERROR){int a = WSAGetLastError();closesocket(socketServer);WSACleanup();return 0;}//收发消息while (1){char buf[1500] = { 0 };int res = recv(socketServer, buf, 50, 0);if (res == 0)//客户端下线,链接中断{printf("链接中断、客户端下线\n");}else if (res == SOCKET_ERROR){printf("出错了\n");int a = GetLastError();//根据实际情况处理}else{printf("服务器说:  %d  %s\n", res, buf);}scanf("%s", buf);int sValue = send(socketServer, buf, strlen(buf), 0);if (sValue == SOCKET_ERROR){int a = WSAGetLastError();closesocket(socketServer);WSACleanup();return 0;}}//清理网络库closesocket(socketServer);WSACleanup();system("pause");return 0;
}

延伸

由于accept,recv是阻塞的,做其中一件事,另一件事就做不了,等着接收客户端的消息-recv,这时来了个链接请求-accept无法处理。(没有目标的等待)

正确的处理方式是——哪个socket有请求就处理谁,得到连接请求,我们就直接accept,得到发来的消息,就recv。(有目的的等待,处理有请求的)

引出select模型

【网络编程】基于TCP/IP协议的C/S模型相关推荐

  1. Linux网络编程——基于tcp/ip的模拟聊天(文件传输)工具

    开发平台:Linux 开发工具:Ubuntu, sourceInsight4.0 项目介绍: 本项目基于TCP/IP协议创建一个网络通信系统,可以实现客户之间的聊天通信以及文件传输,同时利用进程实现多 ...

  2. 网络编程入门 TCP/IP 协议 端口 IP 软件结构

    目录 一.软件结构 二.网络通信协议 三.协议分类: 四.网络编程三要素:协议,ip,端口号 1.协议 2.IP地址 3.IP地址分类 a.IPv4 b.IPv6 4.IP常用命令 1. 查看本机IP ...

  3. 网络编程——基于TCP协议的通讯录【课程设计】

    网络编程--基于TCP协议的通讯录[课程设计] 本文目录 网络编程--基于TCP协议的通讯录[课程设计] 一.设计题目和要求 设计目标: 课程设计系统组成及模块功能: 二.设计内容 服务端 客户端 S ...

  4. 基于TCP/IP协议的网络摄像头的QT项目

    目录 项目简述: 1.服务器 步骤一:首先搭建一个基本的服务器框架. 1.初始化服务器的函数主体 2.等待连接 步骤二:数据库的使用,本次项目使用的Sqlite3数据库 1.数据库初始化 2.登录时使 ...

  5. Linux系统下实现基于TCP/IP协议的简单Socket通信

    Linux系统下实现基于TCP/IP协议的简单Socket通信 网络套接字Socket Socket概念 主机字节序和网络字节序 Sockaddr地址结构 Socket实现客户端.服务端通信 服务端程 ...

  6. 打印服务器协议,基于TCP/IP协议的嵌入式网络打印服务器设计

    摘要: 随着电子技术和计算机网络技术的发展,嵌入式系统在家庭和工业的各个领域都得到了广泛的应用,各种信息家电,网络设备以及工业控制领域都出现了嵌入式系统的身影,其数量已经远远超过了各种通用计算机.但是 ...

  7. 基于TCP/IP协议 区别 GET和POST

    基于TCP/IP协议讲解GET和POST的区别(转载于博客园) 在我大万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象.但是如果路上跑的全是看起来一模一样的汽 ...

  8. 网络编程及TCP/UDP协议

    网络编程 1.1.概述 地球村:你在西安,一个在美国 打电话--连接--接了--通话 TCP 发短信--发完了就完事了--接收 UDP(丢包) 计算机网络: 计算机网络系统就是利用通信设备和线路将地理 ...

  9. 基于TCP/IP协议的物联网安卓应用开发基础教程(Android Studio开发)

    [华为云IOT物联网论坛外部版主:中华小能能] 第0章 简介 大家好,在上上上期发布的教程中,教大家如何利用Android Studio开发出一款接入华为云物联网平台并调用相关API完成设备属性查询. ...

最新文章

  1. iOS - XML 数据解析
  2. discuz php文件,discuz目录文件资料汇总
  3. NUMA架构的CPU -- 你真的用好了么?
  4. Adobe form batch output print mode - multiple
  5. 服务器中有大量CLOSE_WAIT的连接
  6. android studio 手把手叫你NDK开发环境搭建及基础使用
  7. OpenCL编程基本流程及完整示例
  8. java集合uml_Java开源UML建模集合
  9. CnPack开发包基础库
  10. 【人脸识别】基于PCA实现ORL人脸识别附matlab代码和报告
  11. dsniff嗅探工具
  12. win10蓝屏代码_如何让电脑蓝屏 让电脑蓝屏方法介绍【详解】
  13. 霹雳狂刀---回忆录
  14. 面试通知短信模板大全
  15. 其它品牌手机可以刷鸿蒙,定了,鸿蒙系统4月起开始搭载智能手机,其它品牌手机能支持吗?...
  16. 物联网萤石云获取登录的accessToken工具类
  17. 华为手机开机卡在开机画面,该怎么解决呢?
  18. android 电池监测工具,安卓最强电池监控器Battery Monitor Widget Pro
  19. 解决Win11更新后C盘告急
  20. 正常处理数据文件:sh560500.csv None 收盘价_复权 前收盘价 收盘价 复权因子

热门文章

  1. java实现html页面转pdf解决方案_[Java教程]纯js实现html转pdf
  2. python-体质指数BMI计算
  3. 详解 Redis 应用场景及应用实例
  4. 数据库第一天 TAT
  5. css清除浮动float
  6. 美国大学生足球联赛数据集football——node2vec
  7. Autoware感知瞎学笔记(一)lidar_kf_contour_track
  8. 分布式存储与分布式计算
  9. MyEclipse使用教程:unattended安装
  10. HDOJ1495 非常可乐(bfs)