免费1级做爰片在线观看网站,手机app开发软件免费,撰写网站建设规划设计任务书,国家企业信息管理系统同一路由器下两台电脑如何进行通信呢#xff1f;这里通过小程序实例的方式介绍SOCKET结构体以及相关函数的使用。计算机通信是在服务器端与客户端之间进行#xff0c;这里先介绍服务器端程序。 我这里编辑编译软件是VS2022#xff0c;使用C空项目进行编程。在介绍程序… 同一路由器下两台电脑如何进行通信呢这里通过小程序实例的方式介绍SOCKET结构体以及相关函数的使用。计算机通信是在服务器端与客户端之间进行这里先介绍服务器端程序。 我这里编辑编译软件是VS2022使用C空项目进行编程。在介绍程序之前需要提醒大家如果想把这个程序放到没有VS的计算机中使用关于编译设置应如下进行 1.将Debug模式改为Release模式。 2.右键方案名 - 配置属性 - c/c - 代码生成 - 运行库中选 多线程(/MT)。 3.编译后在release目录下如找不到*.exe文件可以在release模式下运行一下程序然后再去找文件即可。 4.如果使用的不是VS也请注意一下编译问题否则运行时会报错缺少某些dll文件。 程序代码及相关解释如下 一、头文件部分最基本的iostream应包含进来并使用标准命名空间免得使用函数时还得注明作用域。WinSock2.h头文件及ws2_32.lib库文件是使用SOCKET结构及相关函数必须的。另外还包含了关于多线程的thread头文件处理通信过程的收和发如不使用多线程方式处理收发之间相互影响会造成不能连续发或连续收。
#includeiostream
using namespace std;
#include WinSock2.h
#pragma comment(lib,ws2_32.lib)
#includethread
#pragma warning (disable: 4996) //解决C4996报错问题 二、声明函数及变量 在这里声明一个接收函数serverAccept和一个发送函数serverSend之所以代码不多还要从主函数中拿出来另写成两个单独函数的原因是因为这两个函数要装到单独的线程中去运行。 需要声明全局变量pubServerSock、pubClientSock的理由也一样主函数中声明的变量在其它线程中使用不了。
void serverRecv();//声明服务器端接收函数
void serverSend(); //声明服务器端发送函数
SOCKET pubServerSock; //声明服务器端全局SOCKET对象
SOCKET pubClientSock; //声明客户端全局SOCKET对象 三、开始主函数代码编写分成一下具体步骤
int main(void)
{ 步骤1. 定义显示窗口。 system(color 1A); //定义窗口前景、背景颜色system(title Server Station); //定义窗口system(mode con cols60 lines30);//定义窗口高宽 步骤2. 打开网络库。打开网络库函数是WSAStartup函数也可以理解成网络库初始化函数。在网络编程中经常见到WSA字头其含义W-windows、S-socket、A-asynchronous异步。这个函数有两个参数参1 系统在用的网络库版本号右键头文件WinSock2 选择 转到文档可看到VS2022对应的网络库版本是2.2。这个版本号在计算机中是以WORD形式存储的参数中不能直接写2.2需要用MAKEWORD宏给转一下。参2 是一个WSADATA类型的结构体对象这个对象需以指针形式传入它的作用是保存一些网络库初始化信息后边需要使用。 打开网络库函数有返回值成功返回0不成功返回非0错误码。 WORD thisVersion MAKEWORD(2, 2); WSADATA SerSockData;int nRes WSAStartup(thisVersion, SerSockData);if(0 ! nRes){cout 网络库打开过程失败程序即将结束 endl;system(pause);return 0; //结束程序运行}
步骤3. 校验版本这一步骤可以略去。如果校验版本未通过在结束程序前也要调用清理网络库函数。 if (2 ! HIBYTE(SerSockData.wVersion) || 2 ! LOBYTE(SerSockData.wVersion)){cout网络库版本出错误程序即将结束endl;system(pause);WSACleanup();return 0; //结束程序运行} 步骤4. 创建服务器端SOCKET对象完成这一步骤的函数是socket函数。socket函数有3个参数这3个参数是按照TCP/IP通信协议要求填写内容不能更改。 socket函数创建成功返回一个可用的SOCKET对象这个对象在后面的操作中要用到它以后就代表着服务器端计算机如果创建失败返回INVALID_SOCKET处理方式还是调用清理网络库函数。 pubServerSock socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET pubServerSock){cout 创建服务器端SOCKET对象失败程序即将结束 endl;system(pause);WSACleanup(); return 0;//结束程序运行} 步骤5. 利用bind函数将计算机IP地址、端口与前面创建的SOCKET对象绑定。这个函数有三个参数参1 是前面创建成功的SOCKET对象参2 是一个结构体这个结构体中要填上本机服务器端IP地址、端口号等内容参3 参2的字节大小。注意函数中需要的是sockaddr*我们填写的是sockaddr_in这个易填所以取址后要强转一下因为这些内容绑定之后不能更改所以强转时加上const。 关于给sockaddr_in结构体对象赋值 a.成员1 sin_family选AF_INET是使用TCP/IP协议必须的 b.成员2 是端口号可取值范围0-65535。低位的多被系统占用了所以要尽量往大了取我这里选的是12345。选好后可以确认一下方法右键开始按钮-点击运行-输入cmd-DOS符号-输入netstat -ano|findstr 12345如果没有什么显示就说明可用如有显示说明系统已经使用了再换一个。htons是一个宏将int转换成sin_port所需格式。 c.成员3 是服务器所在电脑的IP地址。如果是在一台电脑上模拟服务器端和客户端通信IP地址选用127.0.0.1。inet_addr也是一个宏将字符串转换成规定格式。 当在两台电脑运行时填写服务器端电脑的实际IP地址。方法右键开始按钮 - 点击运行 -输入cmd - DOS符号 - 输入ipconfig 选用IPv4后面的地址。 bind函数运行成功会将服务器的SOCKET对象与所在计算机IP地址绑定在一起在网上这个对象就可以代表这台计算机了如果运行失败会返回SOCKET_ERROR接下来先关闭服务器SOCKET对象再清理网络库然后结束这个程序。 sockaddr_in serverSockAdd; serverSockAdd.sin_family AF_INET;serverSockAdd.sin_port htons(12345);serverSockAdd.sin_addr.S_un.S_addr inet_addr(127.0.0.1); //当两台电脑通信使用服务器电脑的IP地址if (SOCKET_ERROR bind(pubServerSock, (const sockaddr*)serverSockAdd, sizeof(serverSockAdd))){cout 绑定服务器IP地址、端口失败程序即将结束 endl;system(pause);closesocket(pubServerSock);WSACleanup(); return 0;//结束整个程序}步骤6. 开启监听函数listen()。监听函数有两个参数参1 服务器端SOCKET对象参2 挂起链接队列的最大长度。这个函数运行成功将把服务器端SOCKET对象置于侦听传入链接的状态如果运行失败还是关闭SOCKET对象、清理网络库然后结束程序。 if (SOCKET_ERROR listen(pubServerSock, SOMAXCONN)){cout 服务器未进入侦听状态程序即将结束 endl;system(pause);closesocket(pubServerSock);WSACleanup();return 0;//结束整个程序} 步骤7. 使用Accept()函数创建客户端链接。在这一步骤服务器将与客户端建立联系。建立联系的方法是在服务器端建立一个客户端的SOCKET对象通过两台计算机双方的SOCKET对象进行联系。这一步骤使用的函数是accept(),它的参数有三个参1 服务器SOCKET对象注意是服务器参2 与bind函数中相同的结构这个结构体是指向客户端的所以不用我们填写参3 参2的长度。 accept()成功返回客户端的SOCKET对象(此时客户端计算机登录)并在屏幕上显示“链接成功”失败返回INVALID_SOCKET失败后的操作还是SOCKET对象、 清理网络库然后结束程序。 sockaddr_in clientSockAdd;int len sizeof(clientSockAdd);pubClientSock accept(pubServerSock,(sockaddr*)clientSockAdd,len);//struct sockaddr*前的const不能加了if (INVALID_SOCKET pubClientSock){cout客户端链接失败程序即将结束endl;closesocket(pubServerSock);WSACleanup(); return 0;//结束整个程序}cout客户端连接成功。。。endl; 步骤8. 与客户端之间接收、发送消息。全局变量及thread的作用在开始介绍头文件时已经介绍此处不再赘述。 thread serverThread1(serverRecv);thread serverThread2(serverSend);serverThread1.join();serverThread2.join(); 步骤9. 程序结束。关闭所有SOCKET对象清理网络库。 closesocket(pubServerSock);closesocket(pubClientSock);WSACleanup(); system(pause);return 0; //程序结束
} 四、子程序的实现 1. serverRecv()是通过多线程对象调用的子程序它的作用是接收客户端发过来的消息并进行显示。使用的函数是recv()。它有3个参数参1 客户端SOCKET对象参2 存储收到消息的字符数组 参3 缓冲内存大小 参4 接收模式一般填0。recv运行正常返回收到的字节数执行失败返回SOCKET_ERROR客户端下线或链接中断返回 0。
void serverRecv()
{while (true){char buf[1024] { 0 };int res recv(pubClientSock, buf, 1024 - 1, 0); if ( SOCKET_ERROR res || 0res){cout 程序运行失败或链接中断 endl;closesocket(pubServerSock);closesocket(pubClientSock);WSACleanup();system(pause);exit(0);}else{cout buf endl; //显示收到的内容}}
} 2.serverSend()也是通过多线程对象调用的子程序它的作用是向客户端发送消息。使用的函数是send(),它的参数个数及类型同及返回值都与recv()相似。
void serverSend()
{while (true){string buf;cin buf;int res send(pubClientSock, buf.c_str(), strlen(buf.c_str()), 0);if (SOCKET_ERROR res){cout 程序运行失败或链接中断。。。 endl;closesocket(pubServerSock);closesocket(pubClientSock);WSACleanup();system(pause);exit(0);}}
}
接下一篇