client.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<stdlib.h>
#include<string>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
void getPub_ip(char *ip)//获取IP
{
//system("curl -L ip.tool.lu >ip.txt");
ShellExecute(NULL, "open", "getip.bat", NULL, NULL, SW_HIDE);
FILE *fp;
fopen_s(&fp, "ip.dat", "r");
wchar_t line[512];
wchar_t line1[512];
fgets(ip, 512, fp);
//fgetws(line, 512, fp);
fclose(fp);
//remove("ip.dat");// 删除文件
}
//获取本机IP及名称
bool GetLocalIP(char * ip, char * hostname)
{
//1.初始化wsa
WSADATA wsaData;
int ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (ret != 0) {
return false;
}
//2.获取主机名
//char hostname[256];
ret = gethostname(hostname, 250);
if (ret == SOCKET_ERROR)
{
return false;
}
//3.获取主机ip
HOSTENT * host = gethostbyname(hostname);
if (host == NULL)
{
return false;
}
//4.转化为char*并拷贝返回
strcpy_s(ip, 250, inet_ntoa(*(in_addr*)*host->h_addr_list));
return true;
}
void main()
{
char localIp[250] = {0};
char localName[250] = { 0 };
char netIp[250] = { 0 };
getPub_ip(netIp);//获取IP
string nip(&netIp[10], strlen(netIp) - 10);
GetLocalIP(localIp, localName);//获取主机名
SOCKET server, client;
char sendstr[128] = { 0 };
int lenght;
SOCKADDR_IN server_add;//定义serverIP及端口
WSADATA wsadata;
//判断版本号
int error = WSAStartup(MAKEWORD(2, 2), &wsadata);
if (error != 0)
{
printf("error");
return;
}
//设置服务器IP
server_add.sin_family = AF_INET;
server_add.sin_addr.S_un.S_addr = inet_addr("111.111.111.111");
server_add.sin_port = htons(8898);
server = socket(AF_INET, SOCK_DGRAM, 0);//创建套接字
int reclen = -1;
GetLocalIP(localIp, localName);//获取主机名
while (1)
{
char recstr[250];
lenght = sizeof(SOCKADDR);
GetLocalIP(localIp, localName);//获取主机名
sendto(server, nip.c_str(), sizeof(netIp) + 1, 0, (SOCKADDR*)&server_add, lenght);
Sleep(2000);
}
closesocket(server);
WSACleanup();
}
server.cpp
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
#include<map>
#include<ctime>
#include<winsock.h>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
map<string, time_t> mapClientMessage;//客户端信息+时间
UINT offLine(LPVOID Param)
{
while (1)
{
Sleep(1000);
string clientMessage;
time_t t;
auto n = mapClientMessage.begin();
for (; n != mapClientMessage.end(); n++)
{
if (time(0) - n->second>10)
{
printf("%s离开服务器\n", n->first.c_str());
mapClientMessage.erase(n->first);
}
}
}
}
void main()
{
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)offLine, NULL, NULL, NULL);//判断是否掉线
SOCKET server,client;
char recstr[256] = { 0 };
int reclen = 0;
int lenght;
SOCKADDR_IN server_add;//定义serverIP及端口
WSADATA wsadata;
//判断版本号
int error = WSAStartup(MAKEWORD(2, 2), &wsadata);
if (error != 0)
{
printf("error");
return;
}
//设置服务器IP
server_add.sin_family = AF_INET;
server_add.sin_addr.S_un.S_addr = inet_addr("111.111.111.111");//指定IP htonl(INADDR_ANY)本机IP
server_add.sin_port = htons(8898);
server = socket(AF_INET, SOCK_DGRAM, 0);//创建套接字
//绑定
bind(server, (SOCKADDR*)&server_add, sizeof(SOCKADDR));
while (1)
{
//printf("11\n");
lenght = sizeof(SOCKADDR);
reclen = recvfrom(server, recstr, sizeof(recstr) + 1, 0, (SOCKADDR*)&server_add, &lenght);
if (reclen != -1)
{
string clientMessage;
time_t t;
auto n = mapClientMessage.begin();
for (;n!=mapClientMessage.end();n++)
{
if (n->first.compare(recstr)==0)//如果链表中有则,插入当前时间
{
n->second = time(0);//获取当前时间,存入
break;
}
if (time(0) - n->second>100)
{
printf("%s离开服务器\n",n->first.c_str());
}
}
if (n == mapClientMessage.end())//如果到末尾,则插入
{
mapClientMessage.insert(make_pair(recstr, time(0)));
printf("%s访问服务器\n", recstr);
}
Sleep(1000);
}
}
closesocket(server);
WSACleanup();
}