在局域网内本地客户端搜索端口号一致的可用服务器并且打印ip地址,即找到网络地址一致的服务器。
客户端
首先需要创建一个客户端:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define IP "192.168.43.201"
int main()
{
printf("服务器创建socket...\n");
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if(0 > sockfd)
{
//perror("socket");
return -1;
}
printf("准备地址...\n");
struct sockaddr_in addr = {};
addr.sin_family = AF_INET;
addr.sin_port = htons(9988);
addr.sin_addr.s_addr = inet_addr(IP);
socklen_t len = sizeof(addr);
printf("绑定socket与地址...\n");
if(bind(sockfd,(struct sockaddr*)&addr,len))
{
perror("bind");
return -1;
}
printf("设置监听...\n");
if(listen(sockfd,5))
{
//perror("listen");
return -1;
}
printf("等待客户端连接...\n");
for(;;)
{
}
}
客户端
然后是客户端,利用Linux系统指令ifconfig查看本地ip,广播地址以及子网掩码,由于广播地址为最大ip,ip最后一段为0则为最小ip,这样就缩小了可用ip的搜索范围。注意编译时需加-lpthread
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "network.h"
int get_ifconfig(in_addr_t* ip,in_addr_t* broad,in_addr_t* mask)
{
system("ifconfig > /tmp/ifconfig.txt");
int fd = open("/tmp/ifconfig.txt",O_RDONLY);
if(0 > fd)
{
perror("open");
return -1;
}
char buf[1024] = {};
read(fd,buf,sizeof(buf));
close(fd);
// 把字符串的ip地址转换成网络字节序4字节整数
char* str = strstr(buf,"地址:")+7;
*ip = inet_addr(str);
str = strstr(str,":")+1;
*broad = inet_addr(str);
str = strstr(str,":")+1;
*mask = inet_addr(str);
return 0;
}
void* find_server(void* arg)
{
char* ip = inet_ntoa(((struct sockaddr_in*)arg)->sin_addr);
NetWork* nw = open_network('c',SOCK_STREAM,ip,6677);
if(NULL != nw)
{
printf("%s\n",inet_ntoa(nw->addr.sin_addr));
}
}
int main()
{
in_addr_t ip,broad,mask;
get_ifconfig(&ip,&broad,&mask);
// 把ip地址从网络字节序转换成本地字节序(为了遍历)
uint32_t min = ntohl(ip)&ntohl(mask)+1 , max = ntohl(broad);
for(uint32_t ip=min; ip<max; ip++)
{
struct sockaddr_in addr;
addr.sin_addr.s_addr = htonl(ip);
pthread_t pid;
pthread_create(&pid,NULL,find_server,&addr);
usleep(100);
}
sleep(3);
}
同时也使用到了网络通信的函数库:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "network.h"
//创建网络连接
NetWork* open_network(char c_or_s,int type,char* ip,uint16_t port)
{
//在堆上创建NetWork结构
NetWork* nw = malloc(sizeof(NetWork));
if(NULL == nw)
{
perror("network malloc");
return NULL;
}
nw->fd = socket(AF_INET,type,0);
if(0 > nw->fd)
{
perror("network socket");
free(nw);
return NULL;
}
//准备通信地址
nw->addr.sin_family = AF_INET;
nw->addr.sin_port = htons(port);
nw->addr.sin_addr.s_addr = inet_addr(ip);
nw->len = sizeof(nw->addr);
nw->type = type;
if('s' == c_or_s)
{
if(bind(nw->fd,(SP)&nw->addr,nw->len))
{
perror("network bind");
free(nw);
return NULL;
}
if(SOCK_STREAM == type && listen(nw->fd,50))
{
perror("network listen");
free(nw);
return NULL;
}
}
else if(SOCK_STREAM == type)
{
if(connect(nw->fd,(SP)&nw->addr,nw->len))
{
//perror("network connect");
free(nw);
return NULL;
}
}
return nw;
}
//TCP的server专用
NetWork* accept__network(NetWork* nw)
{
if(SOCK_STREAM != nw->type)
{
printf("network accept socket type error!\n");
return NULL;
}
NetWork* clinw = malloc(sizeof(NetWork));
if(NULL == clinw)
{
perror("network accept malloc");
return NULL;
}
clinw->type = nw->type;
clinw->len = sizeof(clinw->addr);
clinw->fd = accept(nw->fd,(SP)&clinw->addr,&clinw->len);
if(0 > clinw->fd)
{
perror("network accept");
free(clinw);
return NULL;
}
return clinw;
}
//发送数据
int nsend(NetWork* nw,void* buff,uint32_t len)
{
if(SOCK_STREAM == nw->type)
{
return send(nw->fd,buff,len,0);
}
else if(SOCK_DGRAM == nw->type)
{
return sendto(nw->fd,buff,len,0,(SP)&nw->addr,nw->len);
}
return -1;
}
//接收数据
int nrecv(NetWork* nw,void* buff,uint32_t len)
{
if(SOCK_STREAM == nw->type)
{
return recv(nw->fd,buff,len,0);
}
else if(SOCK_DGRAM == nw->type)
{
return recvfrom(nw->fd,buff,len,0,(SP)&nw->addr,&nw->len);
}
return -1;
}
//关闭网络连接
void close_network(NetWork* nw)
{
if(close(nw->fd))
{
perror("network close");
}
free(nw);
}
执行结果: