懒而又懒的我又来更新笔记了。啊哈哈哈嗝。
最近一周在学校做实训(码代码),选择的项目是远程桌面监控。
然后本萌用了一周时间,从只会C++的零基础,捣鼓出了一个小系统。
小系统的文件我会贴在最后一章笔记上,大家别急鸭!
那就进入正题!
1.SOCKET
了解soket之前首先看看一些网络协议。
1.1 TCP/IP UDP/IP协议
对TCP/IP、UDP这些词,如果是稍有涉及网络的人,应该不会陌生,那什么是TCP/IP、UDP?(其实也是给自己科普)
网络设备之间要相互通信,就必须基于相同的通信方法。就比如你打电话,你们如何检测到基站的信号,基站如何传递你的信号,你如何接受基站信号,这些都是首先需要确定下来的。而网络通信就有着这一套标准,也就是协议(protocol),通过它我们也实现了不同硬件不同设备间的通信。
而在某博客上看到过这样一句话:TCP/IP 是互联网相关的各类协议族的总称,比如:TCP,UDP,IP,FTP,HTTP,ICMP,SMTP 等都属于 TCP/IP 族内的协议。像这样把与互联网相关联的协议集合起来总称为 TCP/IP。也有说法认为,TCP/IP 是指 TCP 和 IP 这两种协议。还有一种说法认为,TCP/IP 是在 IP 协议的通信过程中,使用到的协议族的统称。
为了了解的更清楚,我在这里贴了一个参考模型,能更加清晰明了的看清楚整个TCP/IP的层次结构。
那其实就如图这种分层结构也是TCP/IP协议里的重要的一点。通过分层,简化了整个协议设计,并且可以更加自由的改动层次内部设计,就比如我想改动应用层的某协议,通过分层结构我就不用考虑我如何传输,如何接入对方,只需要考虑我自己的应用方面的东西就行了。
然后后面一坨巴拉巴拉的一堆知识,我也是半壶水,这里就贴个某博客,一起补补知识吧。
1.2 开始写代码
想了想,我要做远程桌面,所以就需要监控端、服务端,所以我要写两个程序出来,然后实现两个程序通过网络进行数据交互。那这里的网络连接呢,由于涉及实时的视频传输,所以我选择的是靠谱点的TCP/IP协议,然后用的是SOCKET(套接字)的 API 。
那现在我们就开始建立SOCKET通信。
服务端
// 然后开始创建一个服务端程序:
#include <WINSOCK2.H> // 这个是需要包含的
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
//1,创建套接字(socket);
WORD myVersionRequest;
WSADATA wsaData;
myVersionRequest=MAKEWORD(1,1);
int err;
err=WSAStartup(myVersionRequest,&wsaData);
if (!err)
{
printf("已打开套接字/n");
}
else
{
//进一步绑定套接字
printf("嵌套字未打开!");
return;
}
SOCKET serSocket=socket(AF_INET,SOCK_STREAM,0);//创建了可识别套接字
//需要绑定的参数
SOCKADDR_IN addr;
// 2, 将套接字绑定到一个本地地址和端口上(bind);
addr.sin_family=AF_INET;
// 这里有一个INADDR_ANY 需要注意的,具体用法我会在代码后面解释
addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//ip地址
addr.sin_port=htons(6000);//绑定端口
bind(serSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR));//绑定完成
listen(serSocket,5);//其中第二个参数代表能够接收的最多的连接数
///
// 3, 将套接字设为监听模式,准备接受客户请求(listen);
SOCKADDR_IN clientsocket;
int len=sizeof(SOCKADDR);
while (1)
{
//4, 等待客户请求到来,当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept);
SOCKET serConn=accept(serSocket,(SOCKADDR*)&clientsocket,&len);
//如果这里不是accept而是conection的话。。就会不断的监听
char sendBuf[100];
//在这我会将指令保存在这个数组里
sprintf(sendBuf," %s is ready",inet_ntoa(clientsocket.sin_addr));//找对对应的IP并且将这行字打印到那里
//5, 用返回的套接字和客户端进行通讯(send/ recv);
send(serConn,sendBuf,strlen(sendBuf)+1,0);
char receiveBuf[100];//接收
//6, 返回等待另一客户请求;
//这里的recv 具有阻塞机制,如果没有马上收到对方发来的信息,
//那么他会一直等待,直到收到信息为止;
recv(serConn,receiveBuf,strlen(receiveBuf)+1,0);
printf("%s/n",receiveBuf);
//7, 关闭套接字;
closesocket(serConn);//关闭
WSACleanup();//释放资源的操作
}
}
以上前4步都是在线程函数中完成的,因为服务器端要一直处于监听状态;
然后后面的recv 和 send 需要在线程进行,因为recv 的阻塞机制会
导致主对话框卡住,影响用户使用。(反正我是这么想的)
客户端(就简单多了)
#include <WINSOCK2.H>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
void main()
{
int err;
// 1, 创建套接字(socket);
WORD versionRequired;
WSADATA wsaData;
versionRequired=MAKEWORD(1,1);
err=WSAStartup(versionRequired,&wsaData);//协议库的版本信息
if (!err)
{
printf("客户端嵌套字已经打开!/n");
}
else
{
printf("客户端的嵌套字打开失败!/n");
return;//结束
}
SOCKET clientSocket=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN clientsock_in;
clientsock_in.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
clientsock_in.sin_family=AF_INET;
clientsock_in.sin_port=htons(6000);
//bind(clientSocket,(SOCKADDR*)&clientsock_in,strlen(SOCKADDR));//注意第三个参数
//listen(clientSocket,5);
//2, 向服务器发送连接请求(connect);
connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));//开始连接
//3, 和服务器进行通讯(send/ recv);
char receiveBuf[100];
recv(clientSocket,receiveBuf,101,0);
printf("%s/n",receiveBuf);
send(clientSocket,"hello,this is client",strlen("hello,this is client")+1,0);
//4, 关闭套接字;
closesocket(clientSocket);
WSACleanup();
}
那么这里添加一个详细的编程步骤同时也是我自己参考的代码来源。
然后基础的连接已经建立了。那…
下一步就是详细的介绍我的客户端和服务端了!以及实现流程了!
等待我的学习笔记(2)更新吧 !