#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
/* struct in6_addr */
#include <netinet/in.h>
/* getifaddrs, freeifaddrs */
#include <sys/types.h>
#ifndef UNSUPPORT_IFADDRS
#include <ifaddrs.h>
#endif
/* inet_ntop, inet_pton */
#include <arpa/inet.h>
#include <net/if.h>
#define MAXBUF 1024
static int get_index(char* ifname)
{
return if_nametoindex (ifname);
}
static int get_linklocal_ipv6addr(char* ipv6address, char *iface)
{
struct in6_addr addr_tmp;
struct ifaddrs *ifa, *p;
int family;
struct in6_addr *addr6=&addr_tmp;
int res = -1;
char address_tmp[200];
if (!iface)
{
printf(" iface can't be NULL!\n");
return -1;
}
if (getifaddrs(&ifa))
{
perror("getifaddrs error");
return -1;
}
for (p = ifa; p != NULL; p = p->ifa_next)
{
//printf("ifa_name = %s, family = 0x%X(%s)\n", p->ifa_name, family,(family == AF_PACKET) ? "AF_PACKET" :(family == AF_INET) ? "AF_INET" : (family == AF_INET6) ? "AF_INET6" : "");
family = p->ifa_addr->sa_family;
/* Just check IPv6 address */
if (family != AF_INET6)
continue;
*addr6 = ((struct sockaddr_in6 *)(p->ifa_addr))->sin6_addr;
/* Just get IPv6 linklocal address of the interface */
if (!strcmp(iface, p->ifa_name) && IN6_IS_ADDR_LINKLOCAL(addr6))
{
if (inet_ntop(AF_INET6, addr6, address_tmp, sizeof(address_tmp)))
{
printf("find out %s's linklocal IPv6 address: %s\n", iface, address_tmp);
strcpy(ipv6address,address_tmp);
res=1;
}
break;
}
}
freeifaddrs(ifa);
return res;
}
int main(int argc, char **argv)
{
int sockfd, new_fd;
socklen_t len;
/* struct sockaddr_in my_addr, their_addr; */ // IPv4
struct sockaddr_in6 my_addr, their_addr; // IPv6
unsigned int myport, lisnum;
char buf[MAXBUF + 1];
char ipv6address[200];
int nc_index;
if (argc != 4)
{
printf("参数格式错误!正确用法如下:\n\t\t%s 监听端口 监听队列数 网卡名称\n\t比如:\t%s 8888 2 ens0\n此程序用来监听某个IP某个端口接收最多 MAXBUF 个字节的消息", argv[0], argv[0]);
exit(0);
}
if (argv[1])
{
myport = atoi(argv[1]);
}
else
{
myport = 7838;
}
printf("端口:%d\n",myport);
if (argv[2])
{
lisnum = atoi(argv[2]);
}
else
{
lisnum = 2;
}
printf("请求队列:%d\n",lisnum);
if ((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1)
{
perror("创建socket");
exit(1);
}
else
{
printf("创建socket成功\n");
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin6_family = PF_INET6;
my_addr.sin6_port = htons(myport);
if (argv[3])
{
my_addr.sin6_scope_id=get_index(argv[3]);
get_linklocal_ipv6addr(ipv6address, argv[3]);
printf("监听IP:%s,网卡编号:%d\n",ipv6address,my_addr.sin6_scope_id);
inet_pton(AF_INET6, ipv6address, &my_addr.sin6_addr);
}
else
{
my_addr.sin6_addr = in6addr_any;
printf("监听全部IP\n");
}
if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr_in6)) == -1) // IPv6
{
perror("bind");
exit(1);
}
else
{
printf("bind成功\n");
}
if (listen(sockfd, lisnum) == -1)
{
perror("listen");
exit(1);
}
else
{
printf("开始监听\n");
}
while (1)
{
len = sizeof(struct sockaddr);
if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &len)) == -1)
{
perror("accept");
exit(errno);
}
else
{
printf("收到连接请求,来自 %s, 端口 %d, socket %d\n", inet_ntop(AF_INET6, &their_addr.sin6_addr, buf, sizeof(buf)), their_addr.sin6_port, new_fd);
}
/* 开始处理每个新连接上的数据收发 */
bzero(buf, MAXBUF + 1);
strcpy(buf, "客户端你好");
/* 发消息给客户端 */
len = send(new_fd, buf, strlen(buf), 0);
if (len < 0)
{
printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n", buf, errno, strerror(errno));
}
else
{
printf("消息发送成功\n");
}
bzero(buf, MAXBUF + 1);
/* 接收客户端的消息 */
len = recv(new_fd, buf, MAXBUF, 0);
if (len > 0)
{
printf("接收消息成功[%d]:'%s'\n", len, buf);
}
else
{
printf("消息接收失败!错误代码是%d,错误信息是'%s'\n", errno, strerror(errno));
}
/* 处理每个新连接上的数据收发结束 */
}
close(sockfd);
return 0;
}
评论0