udp广播
#include <iostream> #include <WinSock2.h> #include <stdio.h> #include <iostream> using namespace std; #pragma comment(lib, "ws2_32.lib") const int MAX_BUF_LEN = 255; #pragma package(smart_init) #pragma resource "*.dfm" class CInitSock { public: CInitSock(BYTE minorVer = 2, BYTE major = 2) //载入Winsock库 { WSADATA wsaData; WORD sockVersion = MAKEWORD(minorVer, major); if (::WSAStartup(sockVersion, &wsaData) != 0) { return; } } ~CInitSock() { ::WSACleanup(); //释放Winsock库 } }; String GetIpAddress() { char cHost[256] = { 0 }; ::gethostname(cHost, 256); //取得本地主机名 hostent* pHost = ::gethostbyname(cHost); //通过主机名得到地址信息 //打印本机Ip地址 in_addr addr; char* p = pHost->h_addr_list[0]; if (p == NULL) { return ""; } memcpy(&addr.S_un.S_addr, p, pHost->h_length); char* cIp = ::inet_ntoa(addr); cout << "本机IP:" << cIp << endl; String s = cIp; return s; } void broadcast_ip(String s) { // 创建socket SOCKET connect_socket; connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (INVALID_SOCKET == connect_socket) { int err = WSAGetLastError(); printf("socket error! error code is %d/n", err); return ; } SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = htons(3779); sin.sin_addr.s_addr = INADDR_BROADCAST; bool bOpt = true; //设置该套接字为广播类型 setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt)); int nAddrLen = sizeof(SOCKADDR); char buff[MAX_BUF_LEN] = ""; int nLoop = 0; while (1) { nLoop++; sprintf(buff, "%s", s.c_str()); // 发送数据 int nSendSize = sendto(connect_socket, buff, strlen(buff), 0, (SOCKADDR*)&sin, nAddrLen); if (SOCKET_ERROR == nSendSize) { int err = WSAGetLastError(); printf("sendto error!, error code is %d/n", err); return ; } printf("Send: %s/n", buff); Sleep(500); } } int get_serverip() { // 创建socket SOCKET connect_socket; connect_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (INVALID_SOCKET == connect_socket) { err = WSAGetLastError(); printf("socket error! error code is %d/n", err); return -1; } // 用来绑定套接字 SOCKADDR_IN sin; sin.sin_family = AF_INET; sin.sin_port = htons(3779); sin.sin_addr.s_addr = 0; // 用来从网络上的广播地址接收数据 SOCKADDR_IN sin_from; sin_from.sin_family = AF_INET; sin_from.sin_port = htons(3779); sin_from.sin_addr.s_addr = INADDR_BROADCAST; //设置该套接字为广播类型, bool bOpt = true; setsockopt(connect_socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOpt, sizeof(bOpt));
struct timeval tv_out;
tv_out.tv_sec = 1000;//等待1秒
tv_out.tv_usec = 0;
setsockopt(
connect_socket
,SOL_SOCKET,SO_RCVTIMEO,&tv_out, sizeof(tv_out));
// 绑定套接字 err = bind(connect_socket, (SOCKADDR*)&sin, sizeof(SOCKADDR)); if (SOCKET_ERROR == err) { err = WSAGetLastError(); printf("bind error! error code is %d/n", err); return -1; } int nAddrLen = sizeof(SOCKADDR); char buff[MAX_BUF_LEN] = ""; int nLoop = 0; while (1) { // 接收数据 int nSendSize = recvfrom(connect_socket, buff, MAX_BUF_LEN, 0, (SOCKADDR*)&sin_from, &nAddrLen); if (SOCKET_ERROR == nSendSize) { err = WSAGetLastError(); printf("recvfrom error! error code is %d/n", err); return -1; } buff[nSendSize] = '\0'; String s = buff; ShowMessage(s); break; } }
线程函数
DWORD WINAPI ThreadFunc(LPVOID lpParam) { CInitSock intSock; if(get_serverip()!="") { ShowMessage("在局域网里面已存在服务器"); } broadcast_ip(GetIpAddress()); }
工程测试代码
// 启动服务器 //初始化Winsock库 CInitSock initSock; //打印本机Ip地址 String s = GetIpAddress(); broadcast_ip(s); // 客户端 CInitSock initSock; get_serverip(); void __fastcall TForm1::FormCreate(TObject *Sender) //初始化Winsock库 CInitSock initSock; //打印本机Ip地址 String s = GetIpAddress(); if(s!=""){ // 不能启动服务器 }

浙公网安备 33010602011771号