2、实现流程图
网络通信如何识别通讯双方:(五元组) 一个本机IP对应自己的电脑,远程IP对应一个别人的电脑; 以及电脑有多个运行的程序,用端口号区分不同的程序
并且使用协议名最终确定
INADDR_ANY
泛指本机IP(即0.0.0.0)#define INADDR_ANY (ULONG)0x00000000
客户端和服务端的地址设置: 地址都是表明自己的,所以服务端必然是本机,客户端就是其他人电脑对应的IP
3、代码分段解读(其实算是分功能)借用丙佬的图,顺便附上链接基于 UDP 的套接字通信 | 爱编程的大丙 (subingwen.cn)
(本质上我自己没有完成互相通讯,只有一个单向传播嘤嘤嘤)
4、实现代码
/*初始化WSA*/ WSADATA data; //创建对象 int error = WSAStartup(MAKEWORD(2, 2), &data);//WSA 是windows socket api,这里创建一个对象?可以回来补充!;MAKEWORD(2,2)是使用version2.2的套接字 if (error != 0) { printf("error\n"); return 1; } //这里检查版本对不对,高字节是主版本,低字节是副版本 if (HIBYTE(data.wVersion) != 2 || LOBYTE(data.wVersion) != 2) { WSACleanup(); printf("version wrong\n"); return 0; }
/*实例化SOCKET*/ SOCKET client_sock = socket(AF_INET, SOCK_DGRAM, 0); //第一个是地址类型;第二个是套接字类型;第三个是要使用的通讯协议 //其他参数见官方doc //https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-socket
/*实例化SOCKADDR_IN*/ SOCKADDR_IN server_address; //三个主要属性:1.sin_addr 表示socket收发地址,这是一个结构体;常见的有 server_address.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //或者↓这下面的是wsa2.h的表达方式 inet_pton(AF_INET, "10.136.122.138", &server_address.sin_addr.S_un.S_addr); // 2.sin_family 如果用socket编程,似乎只能用AF_INET // 3.sin_port 表示该程序的端口号(自己找一个空闲的端口号),有需要对应htons函数 //具体举个例子 server_address.sin_family = AF_INET; server_address.sin_port = htons(6666);
/*绑定套接字和地址*/ bind(server_sock, (SOCKADDR*)&server_address, sizeof(SOCKADDR));
/*初始化一些用于收发的存储量*/ int len = sizeof(SOCKADDR); char send_buffer[100] = "abbbbb";
最后简单介绍一下
sendto
和recvfrom
的用法 (1)函数原型int WSAAPI sendto( [in] SOCKET s, [in] const char *buf, [in] int len, [in] int flags, [in] const sockaddr *to, [in] int tolen ); //举个例子 sendto(client_sock, send_buffer, strlen(send_buffer) + 1, 0, (SOCKADDR*)&server_address, len); //这个是客户端发给服务端的句子;第一项就是使用者端的套接字 // 第二项目是发送的字符串 // 第三项是这个字符串的长度 // 第四项俺也不太会,一般默认0 // 第五项是发送给的东西的地址,传参传sockaddr结构体的指针 // 第六项是这个sockaddr的大小;int len = sizeof(SOCKADDR);
int WSAAPI recvfrom( [in] SOCKET s, [out] char *buf, [in] int len, [in] int flags, [out] sockaddr *from, [in, out, optional] int *fromlen ); //举个例子 recvfrom(server_sock, recieve_buffer, sizeof(recieve_buffer), 0, (SOCKADDR*)&client_address, &len); //这个是服务端接受客户端发送来的信息的例子;第一项是使用者的套接字 // 第二项是存信息的数组 // 第三项是这个数组长度 // 第四项同上,默认0吧 // 第五项是数据来源的地址,传的同样是sockaddr的指针 // 第六项同前
(1)功能提醒:就是简单的客户端发,服务端收;这种最基础的都大同小异,可能得掌握bind、端口等具体含义与作用后拓展会更好(这只小菜狗想试着做个狼人杀系统,但是可能大概率寄)
(2)客户端
#include
#include #include #include #pragma comment(lib, "Ws2_32.lib") int main(void) { WSADATA data; int error = WSAStartup(MAKEWORD(2, 2), &data); if (error != 0) { printf("error\n"); return 1; } if (HIBYTE(data.wVersion) != 2 || LOBYTE(data.wVersion) != 2) { WSACleanup(); printf("version wrong?\n"); return 0; } SOCKET client_sock = socket(AF_INET, SOCK_DGRAM, 0); //这里考虑去掉,晚上回来试试 SOCKADDR_IN client_address; inet_pton(AF_INET, "10.136.210.98", &client_address.sin_addr.S_un.S_addr);//这里记得换一下,变成其他电脑的ip client_address.sin_family = AF_INET; client_address.sin_port = htons(6666); //去掉↑ //手动加 SOCKADDR_IN server_address; inet_pton(AF_INET, "我自己电脑(服务端)的ip", &server_address.sin_addr.S_un.S_addr); server_address.sin_family = AF_INET; server_address.sin_port = htons(6666); int len = sizeof(SOCKADDR); char send_buffer[100] = "abbbbb"; printf("Connection established,send \'#\' to disconnect.\n"); while (1) { puts("enter sth to send:"); gets_s(send_buffer); sendto(client_sock, send_buffer, strlen(send_buffer) + 1, 0, (SOCKADDR*)&server_address, len); } closesocket(client_sock); WSACleanup(); return 0; } (3)服务端
#include
#include #include #include #include #pragma comment(lib, "Ws2_32.lib") int main(void) { WSADATA data; int error = WSAStartup(MAKEWORD(2, 2), &data); if (error != 0) { printf("error\n"); return 1; } if (HIBYTE(data.wVersion) != 2 || LOBYTE(data.wVersion) != 2) { WSACleanup(); printf("version wrong?\n"); return 0; } SOCKET server_sock = socket(AF_INET, SOCK_DGRAM, 0); SOCKADDR_IN server_address; server_address.sin_addr.S_un.S_addr = inet_addr("我自己电脑的ip"); server_address.sin_family = AF_INET; server_address.sin_port = htons(6666); int flag = bind(server_sock, (SOCKADDR*)&server_address, sizeof(SOCKADDR)); if (flag == -1) puts("eeee"); SOCKADDR_IN client_address; //这里加进去的 client_address.sin_addr.S_un.S_addr = inet_addr("10.135.7.112");//这里记得换一下,变成其他电脑的ip client_address.sin_family = AF_INET; client_address.sin_port = htons(6666); //这里加入 int len = sizeof(client_address); char recieve_buffer[100], send_buffer[100] = "abbbbbbbbbbbbbbbbbb", tmp_buffer[30]; printf("Connection established,send \'#\' to disconnect.\n"); while (1) { recvfrom(server_sock, recieve_buffer, sizeof(recieve_buffer), 0, (SOCKADDR*)&client_address, &len); puts("recieved\n"); printf("%s\n", recieve_buffer); } closesocket(server_sock); WSACleanup(); return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)