UDP 广播的使用
程序员文章站
2022-03-04 20:46:34
...
使用UDP广播获取server端的IP地址。
1. server开启broadcast监听
void *testBroadcast(void *argv){
int detachCode = pthread_detach(pthread_self());// 将状态改为unjoinable状态,确保资源的释放
printf("testBroadcast thread: detachCode = %d\n", detachCode);
// Receive command from Phone
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(UDP_BROADCAST_RECEIVE_IP_PORT); //6005
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if ((broadcastSockId = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Broadcast IP:: socket fail");
exit(1);
}
// reuse socket port
int on=1;
if (setsockopt(broadcastSockId, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int))<0) {
perror("Broadcast IP:: setsockopt");
}
if (bind(broadcastSockId, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("Broadcast IP:: bind fail");
exit(1);
}
char receivedCmd[1024] = {0};
struct sockaddr_in clientAddr;
socklen_t len = sizeof(clientAddr);
// char *p;
while (1 && isWifiNetworkSecure) {
printf("\t%s: Broadcast IP:: waiting for new command...\n", APP_TAG.c_str());
memset(receivedCmd,0x00,1024);
int ret=recvfrom(broadcastSockId, receivedCmd, 1024, 0, (struct sockaddr*)&clientAddr, &len);
mSenderIPAddress = inet_ntoa(clientAddr.sin_addr);
int client_port = ntohs(clientAddr.sin_port);
printf("Broadcast IP:: client port: %d\n", client_port);
mWisCommon.sysLocalTime(("Broadcast IP::receive from " + mSenderIPAddress).c_str());
if(ret<=0) {
printf("\t%s: Broadcast IP:: read error...\n", APP_TAG.c_str());
continue;
} else {
if (strlen(receivedCmd) <= 0) {
continue;
}
printf("\t%s: Broadcast IP:: Run action with command...%s\n", APP_TAG.c_str(), receivedCmd);
printf("receivedCmd: %s\n", receivedCmd);
std::string recv_content = receivedCmd;
if (recv_content.find(CMD_FIND_DEVICES) != string::npos) {
printf("\t%s: Broadcast findMe:: find devices...\n", APP_TAG.c_str());
// get Helios UUID
std::string uuid=mWisCommon.getDeviceUuid();
// get Helios IP
std::string ip=mWisCommon.getIPAddress();
//Generated JSON
std::string sendContent;
rapidjson::Document document;
document.SetObject();
rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
rapidjson::Value content(rapidjson::kObjectType);
content.AddMember("ip",ip,allocator);
content.AddMember("uuid",uuid,allocator);
// rapidjson::Value root(rapidjson::kObjectType);
rapidjson::Value settings(rapidjson::kObjectType);
settings.AddMember("broadcast",content,allocator);
document.AddMember("Response",settings,allocator);
rapidjson::StringBuffer buffer;
rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
document.Accept(writer);
sendContent = buffer.GetString();
std::cout << sendContent << std::endl;
// Send data:
// mWisCommon.sendUDPDataToSender(mSenderIPAddress, sendContent);
mWisCommon.sendUDPDataToSenderSpecifyPort(mSenderIPAddress, client_port, sendContent);
}
}
}
close(broadcastSockId);
pthread_exit(0);
return 0;
}
2. 将IP地址信息发送给client端
void WisCommon::sendUDPDataToSenderSpecifyPort(std::string senderIPAddress, int port, std::string sendContent){
pthread_mutex_lock(&sendUDPDataToSenderMutex);
if (senderIPAddress.length() <= 0) {
printf("WisCommon::sendUDPDataToSender senderIPAddress is null, so ignore this send.\n");
}else{
sendContent += "\n";
int socketfd;
socklen_t addr_len;
struct sockaddr_in server_addr;
if((socketfd = socket(PF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
}else{
printf("socketfd = %d\n",socketfd);
int i=1;
socklen_t len = sizeof(i);
setsockopt(socketfd,SOL_SOCKET,SO_BROADCAST,&i,len);
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(senderIPAddress.c_str());
server_addr.sin_port = htons(port);
addr_len=sizeof(server_addr);
printf("send content is: %s\n", sendContent.c_str());
int ret=sendto(socketfd, sendContent.c_str(), sendContent.length(), 0, (struct sockaddr*)&server_addr, addr_len);
if(ret<0){
printf("\t\t\t\tsend avs data error....\n");
}else{
printf("\t\t\t\tsend avs data ok \n");
}
close(socketfd);
}
}
pthread_mutex_unlock(&sendUDPDataToSenderMutex);
}
3. client测试发送
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define HELLO_PORT 6005
//#define HELLO_GROUP "225.0.0.37" //224.0.0.251
#define HELLO_GROUP "224.0.0.251" //224.0.0.251
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, cnt;
struct ip_mreq mreq;
char *message="Hello, World!";
/* create what looks like an ordinary UDP socket */
if ((fd=socket(AF_INET,SOCK_DGRAM,0)) < 0)
{
perror("socket");
exit(1);
}
/* set up destination address */
memset(&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(HELLO_GROUP);
addr.sin_port=htons(HELLO_PORT);
/* now just sendto() our destination! */
//while (1)
// {
if (sendto(fd,message, strlen(message), 0, (struct sockaddr *) &addr, sizeof(addr)) < 0)
{
perror("sendto");
exit(1);
}
sleep(1);
//}
return 0;
}
4.android UDP client code:
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
public class UDPHelper {
private static final String TAG = "xxx";
private Boolean IsThreadDisable = false;//指示监听线程是否终止
private WifiManager.MulticastLock lock;
private InetAddress mUniqueAddress,MultiAddress;
private int server_port = 6000; // UDP服务器监听的端口
private DatagramSocket socket = null; // UDP socket
private DatagramSocket mUDPSocket;
private MulticastSocket Multisocket;
private String curversion = null,amazon_name = "";
private WifiManager manager;
private static UDPHelper instance = null;
public static UDPHelper getInstance(WifiManager wifiManager){
if(instance == null){
instance = new UDPHelper(wifiManager);
}
return instance;
}
private UDPHelper(WifiManager manager) {
Log.i(TAG,"udp helper initial");
// 20171103 multicast lock
this.manager = manager;
initial();
new Thread(new Runnable() {
@Override
public void run() {
startToReceive(6002);
}
}).start();
}
private void allowMulticast(){
lock = manager.createMulticastLock("multicast.test");
lock.acquire();
}
private void initial() {
try {
socket = new DatagramSocket();
} catch (SocketException e) {
e.printStackTrace();
Log.i(TAG, "create socket exception: " + e.getMessage());
}
}
private void setMultiSocket(){
try {
Multisocket = new MulticastSocket(server_port);
//server_port=6000;
String multiIP = "224.0.0.251";
MultiAddress = InetAddress.getByName(multiIP);
Multisocket.setTimeToLive(1);
Multisocket.setLoopbackMode(false);
// Multisocket.setInterface(MultiAddress);
Multisocket.joinGroup(MultiAddress);
Log.i(TAG, "multisocket=" +"IP="+MultiAddress+"\nMultisocket="+Multisocket);
} catch (SocketException e) {
e.printStackTrace();
Log.i(TAG, "create socket exception: " + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
private void startToReceive(int localPort) {
try {
mUDPSocket = new DatagramSocket(localPort);
while (true){
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
mUDPSocket.receive(packet);
//String strMsg = new String(packet.getData()).trim();
String strMsg = new String(data, 0, packet.getLength()).trim();
Log.d(TAG, packet.getAddress()
.getHostAddress()
+ ":" + strMsg);
if(listener != null){
listener.receive(strMsg);
receiveCount++;
Log.i(TAG,"send="+sendCount+"\n"+"receive="+receiveCount);
}
}
}catch (IOException e){
e.printStackTrace();
}
}
private int sendCount,receiveCount;
public void sendMulti(final String message) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
sendSyncMulti(message);
}
});
}
private void sendSyncMulti(String message){
//20171103
allowMulticast();
setMultiSocket();
String msg = (message == null ? "Hello!" : message);
int msg_length = msg.length();
byte[] messageByte = msg.getBytes();
Log.i(TAG, "ipaddress: " +MultiAddress+"port:"+server_port+"\nsocket:"+Multisocket);
DatagramPacket p = new DatagramPacket(messageByte, msg_length, MultiAddress,
server_port);
try {
if (Multisocket != null && MultiAddress != null) {
Multisocket.send(p);
}
sendCount++;
} catch (IOException e) {
e.printStackTrace();
Log.i(TAG, "send exception: " + e.getMessage());
}finally {
try{
if (Multisocket != null) {
// Multisocket.disconnect(); 20171103
Multisocket.close();
Multisocket = null;
}
Log.i(TAG,"release multi socket");
}catch (Exception e){
e.printStackTrace();
}
try {
if (lock != null){
lock.release();
lock = null;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
public void destroy() {
if (lock != null){
lock.release();
lock = null;
}
Log.i(TAG,"release lock");
if (mUDPSocket != null) {
//mUDPSocket.disconnect();
Log.i(TAG,"release udp socket disconnect");
mUDPSocket.close();
Log.i(TAG,"release udp socket close");
mUDPSocket = null;
}
Log.i(TAG,"release udp socket");
if (Multisocket != null) {
// Multisocket.disconnect(); 20171103
Multisocket.close();
Multisocket = null;
}
Log.i(TAG,"release multi socket");
if (socket != null) {
socket.disconnect();
socket.close();
socket = null;
}
Log.i(TAG,"release socket");
instance = null;
}
public interface UDPHelperListener{
void receive(String data);
}
private UDPHelperListener listener = null;
public void setUDPHelperListener(UDPHelperListener listener){
this.listener = listener;
}
}
上一篇: Nodejs中使用mysql