smartconfig 實際就是 手機端發送多播一串經過處理的數據,然后接收端,接受到這個數據之后,解析到wifi密碼,連接上wifi,在實現過程中可能遇到的問題如下:
1. send socket的設置
SOCKET sendSock = socket(AF_INET,SOCK_DGRAM,0); if (sendSock == INVALID_SOCKET) { printf("socket error\n"); return -1; } int n = 1; ret = setsockopt(sendSock, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&n, sizeof(n)); if (0 != ret) { printf("setsockopt error\n"); return -1; }
需要將sock設置為廣播模式,在 將數據組裝以后,發送數據時:
ssize_t ret = sendto(sendSock, buf, strlen(buf) + 1, 0, (sockaddr*)&addr, sizeof(sockaddr)); if (ret == SOCKET_ERROR) { printf("sendto error!\n"); }
其中地址,為你多播的地址,不同的協議發送的地址,不一樣,看你的芯片。
2. 手機接受返回數據如下:
SOCKET recvSock = socket(AF_INET, SOCK_DGRAM, 0); if (INVALID_SOCKET == recvSock) { printf("socket error\n"); return -1; } sockaddr_in recvAddr; recvAddr.sin_family = AF_INET; recvAddr.sin_addr.s_addr = INADDR_ANY; recvAddr.sin_port = htons(8068); int ret = bind(recvSock, (sockaddr*)&recvAddr, sizeof(recvAddr)); if (ret != 0) { printf("bind error\n"); return -1; } //用一個保留地址,用作監聽 ip_mreq multiCast; multiCast.imr_interface.s_addr = INADDR_ANY; multiCast.imr_multiaddr.s_addr = inet_addr("236.236.238.50"); ret = setsockopt(recvSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multiCast, sizeof(multiCast)); if (0 != ret) { printf("setsockopt error\n"); return -1; }
socket的創建;
socket接受時的處理:
do { timeout.tv_sec=0; timeout.tv_usec=500000; FD_ZERO(&readset); FD_SET(recvSock,&readset); int result=select(recvSock+1,&readset,NULL,NULL,&timeout); printf("the result is %d\n",result); if(FD_ISSET(recvSock,&readset)>0) { socklen_t len = sizeof(sockaddr); char buf[100] = {0}; printf("start recv\n"); ssize_t ret = recvfrom(recvSock, buf, sizeof(buf) - 1, 0, (sockaddr*)&recvAddr, &len); if (ret == SOCKET_ERROR) { printf("recvfrom error!\n"); return -1; } printf("recv len is %d\n,the data is %s\n the strlen is %ld",len,buf,strlen(buf));
//處理數據 }while(1)
目前不再使用 發送信道數據的長度來截取密碼和SSID了,不安全也又可能失敗。