服务器端:
// Server.cpp : Defines the entry point for the console application.
//
#include "stdio.h"
#include <iostream>
using namespace std;
#include <string>
#include <WINSOCK2.H>
#pragma comment(lib, "wsock32.lib")
#define SERVER_EXIT_OK 0 //服务器正常退出
#define SERVER_DLL_REEOR 1 //调用Windows sockets DLL失败
#define SERVER_API_ERROR 2 //调用Windows sockets API失败
#define SERVERPORT 5555//服务器TCP端口
#define MAX_NUM_BUF 64 //缓冲区最大尺寸
//变量
char bufRecv[MAX_NUM_BUF]; //读缓冲区
char bufSend[MAX_NUM_BUF]; //写缓冲区
SOCKET sServer; //服务器监听套接字
BOOL bConning; //与客户端的连接状态
//函数
void InitMember(void); //初始化成员变量
int ExitClient(int nExit); //客户端退出
int HandleSocketError(char *str); //对Windows sockets API调用错误处理
//主函数
int main(int argc, char* argv[])
{
InitMember();
WORD wVersionRequested; //应用程序需要Windows sockets DLL的版本
WSADATA wsaData; //Windows sockets DLL版本信息
int retVal; //调用Windows sockets API返回值
//初始化Windows Sockets DLL
wVersionRequested = MAKEWORD(1,1);
retVal = WSAStartup(wVersionRequested, &wsaData);
if ( 0 != retVal )
{
cout<<"Can not find a usable Windows Sockets dll!";
return SERVER_DLL_REEOR;
}
//确保WinSock DLL支持1.1
if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1)
{
cout<<"Can not find a usable Windows Sockets dll!";
WSACleanup( );
return SERVER_DLL_REEOR;
}
//创建一个数据报套接字用于发送广播信息
sServer = socket(AF_INET, SOCK_DGRAM, 0);//UDP(SOCK_DGRAM)
if(INVALID_SOCKET == sServer)
{
return HandleSocketError("Failed socket()!");
}
//设置广播选项,使SO_BROADCAST选项有效
BOOL bBroadcast = true;
setsockopt(sServer, SOL_SOCKET, SO_BROADCAST,
(char*)&bBroadcast, sizeof(BOOL));
/*sockfd:标识一个套接口的描述字。
level:选项定义的层次;支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
optname:需设置的选项。
optval:指针,指向存放选项值的缓冲区。
optlen:optval缓冲区长度。*/
//设置广播地址及广播端口号,这时的接收方地址应该设为地址INADDR_BROADCAST
SOCKADDR_IN bcast;
bcast.sin_addr.s_addr = INADDR_BROADCAST;
//::inet_addr("255.255.255.255");
bcast.sin_family = AF_INET;
bcast.sin_port = htons(SERVERPORT);
//绑定套接字
retVal = bind(sServer, (LPSOCKADDR)&bcast, sizeof(SOCKADDR_IN));
printf(" 开始向网络中发送广播数据... \n \n");
char sz[] = "This is just a test. \r\n";
while(TRUE)
{
sendto(sServer, sz, strlen(sz), 0, (sockaddr*)&bcast, sizeof(bcast));
/*s:一个标识套接口的描述字。
buf:包含待发送数据的缓冲区。
len:buf缓冲区中数据的长度。
flags:调用方式标志位。
to:(可选)指针,指向目的套接口的地址。
tolen:to所指地址的长度。*/
Sleep(5000);
}
//退出
return ExitClient(SERVER_EXIT_OK);
}
/*
* 初始化成员变量
*/
void InitMember(void)
{
//初始化读和写缓冲区
memset(bufRecv, 0, MAX_NUM_BUF);
memset(bufSend, 0, MAX_NUM_BUF);
//初始化
sServer = INVALID_SOCKET;
//没有连接状态
bConning = FALSE;
}
/*
* 错误处理
*/
int HandleSocketError(char *str)
{
cout<<str; //显示错误消息
WSACleanup(); //卸载Windows socket DLL
return SERVER_API_ERROR;//退出应用程序
}
/*
* 退出
*/
int ExitClient(int nExit)
{
closesocket(sServer); //关闭监听套接字
WSACleanup(); //卸载Windows sockets DLL 清理内存
return nExit; //退出
}
客户端:
// Client.cpp : Defines the entry point for the console application.
//
#include "stdio.h"
#include <iostream>
using namespace std;
#include <string>
#include <WINSOCK2.H>
#pragma comment(lib, "wsock32.lib")
#define SERVER_EXIT_OK 0 //服务器正常退出
#define SERVER_DLL_REEOR 1 //调用Windows sockets DLL失败
#define SERVER_API_ERROR 2 //调用Windows sockets API失败
#define SERVERPORT 5555//服务器TCP端口
#define MAX_NUM_BUF 64 //缓冲区最大尺寸
//变量
char bufRecv[MAX_NUM_BUF]; //读缓冲区
char bufSend[MAX_NUM_BUF]; //写缓冲区
SOCKET sClient; //接受客户端套接字
BOOL bConning; //与客户端的连接状态
//函数
void InitMember(void); //初始化成员变量
int ExitClient(int nExit); //客户端退出
int HandleSocketError(char *str);
//主函数
int main(int argc, char* argv[])
{
InitMember();
WORD wVersionRequested; //应用程序需要Windows sockets DLL的版本
WSADATA wsaData; //Windows sockets DLL版本信息
int retVal; //调用Windows sockets API返回值
//初始化Windows Sockets DLL
wVersionRequested = MAKEWORD(1,1);
retVal = WSAStartup(wVersionRequested,(LPWSADATA)&wsaData);
if ( 0 != retVal )
{
cout<<"Error";
//MessageBox(NULL, "Can not find a usable Windows Sockets dll!", "ERROR", MB_OK);
return SERVER_DLL_REEOR;
}
//创建一个数据报套接字用于接收广播信息
sClient = socket(AF_INET, SOCK_DGRAM, 0);
if(INVALID_SOCKET == sClient)
{
return HandleSocketError("Failed socket()!");
}
LPHOSTENT hostEntry;
char hostname[MAX_NUM_BUF];
gethostname(hostname,MAX_NUM_BUF); //获取主机名称
hostEntry = gethostbyname(hostname); //获取主机信息
if(!hostEntry)
{
; //显示错误信息
return ExitClient(SERVER_API_ERROR); //退出
}
printf(" 开始接收广播数据... \n\n");
//绑定一个本地地址,指明广播端口号(要和发送方设置端口号的相同)作为接收端口。
SOCKADDR_IN addrRemote;
addrRemote.sin_family = AF_INET;
addrRemote.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
//addrServ.sin_addr.s_addr = inet_addr("10.20.255.183");
addrRemote.sin_port = htons(SERVERPORT);
retVal = bind(sClient, (LPSOCKADDR)&addrRemote, sizeof(SOCKADDR_IN));
int nLen = sizeof(addrRemote);
char sz[256];
while(TRUE)
{
int nRet = recvfrom(sClient, sz, 256, 0, (sockaddr*)&addrRemote, &nLen);
/*sockfd:标识一个已连接套接口的描述字。
buf:接收数据缓冲区。
len:缓冲区长度。
flags:调用操作方式。是以下一个或者多个标志的组合体,可通过or操作连在一起:
from:(可选)指针,指向装有源地址的缓冲区。
fromlen:(可选)指针,指向from缓冲区长度值。*/
if(nRet > 0)
{
sz[nRet] = '\0';
printf(sz);
}
}
//退出
return ExitClient(SERVER_EXIT_OK);
}
/*
* 初始化成员变量
*/
void InitMember(void)
{
//初始化读和写缓冲区
memset(bufRecv, 0, MAX_NUM_BUF);
memset(bufSend, 0, MAX_NUM_BUF);
//初始化
sClient = INVALID_SOCKET;
//没有连接状态
bConning = FALSE;
}
/*
* 错误处理
*/
int HandleSocketError(char *str)
{
cout<<str; //显示错误消息
WSACleanup(); //卸载Windows socket DLL
return SERVER_API_ERROR;//退出应用程序
}
/*
* 退出
*/
int ExitClient(int nExit)
{
closesocket(sClient); //关闭连接客户端套接接
WSACleanup(); //卸载Windows sockets DLL 清理内存
return nExit; //退出
}
服务器端:
客户端: