linux c setsockopt 设置ttl

TTL
TTL是 Time To Live的缩写,该字段指定IP包被路由器丢弃之前允许通过的最大网段数量。TTL是IPv4包头的一个8 bit字段.

在IPv4包头中TTL是一个8 bit字段,它位于IPv4包的第9个字节。如下图所示,每

一行表示 32 bit(4字节),位从0开始编号,即0~31。
 

 

TTL的作用是限制IP数据包在计算机网络中的存在的时间。TTL的最大值是255,TTL的一个推荐值是64.

虽然TTL从字面上翻译,是可以存活的时间,但实际上TTL是IP数据包在计算机网络中可以转发的最大跳数。TTL字段由IP数据包的发送者设置,在IP数据包从源到目的的整个转发路径上,每经过一个路由器,路由器都会修改这个TTL字段值,具体的做法是把该TTL的值减1,然后再将IP包转发出去。如果在IP包到达目的IP之前,TTL减少为0,路由器将会丢弃收到的TTL=0的IP包并向IP包的发送者发送 ICMP time exceeded消息。

TTL的主要作用是避免IP包在网络中的无限循环和收发,节省了网络资源,并能使IP包的发送者能收到告警消息。

TTL 是由发送主机设置的,以防止数据包不断在IP互联网络上永不终止地循环。转发IP数据包时,要求路由器至少将 TTL 减小 1。

Windows
TTL值的注册表位置HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters 其中有个DefaultTTL的DWORD值,其数据就是默认的TTL值了,我们可以修改,但不能大于十进制的255。Windows系统设置后重启才生效。

Linux
linux系统 TTL值的修改位置是/proc/sys/net/ipv4/ip_default_ttl,

echo 128 > /proc/sys/net/ipv4/ip_default_ttl

  若要设置长久的可以:

  修改/etc/sysctl.conf配置文件,添加如下一行

  net.ipv4.ip_default_ttl=128
 

#include <sys/types.h>
#include <sys/socket.h>
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
 
  int ttl = 64;
  int yes = 1;
  setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));  //设置组播TTL
  setsockopt(fd, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)); //set ttl  on all sockets
  setsockopt(fd, IPPROTO_IP, IP_RECVTTL , &yes, sizeof(yes));//Tell me the TTL of incomming packets.

server.c

#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
 
#define PORT 8900
 
int main(int argc,char** argv)
{
	struct sockaddr_in server;
	struct sockaddr_in client;
	int len;
	int port;
	int listend;
	int connectd;
	int sendnum;
	int opt;
	int recvnum;
	char send_buf[2048];
	char recv_buf[2048];
 
 
	port= PORT;
	memset(send_buf,0,2048);
	memset(recv_buf,0,2048);
	
    opt = SO_REUSEADDR;
      
 
    if (-1==(listend=socket(AF_INET,SOCK_STREAM,0)))
    {
	 perror("create listen socket error\n");
	 exit(1);
    }
    setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
 
 
    memset(&server,0,sizeof(struct sockaddr_in));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(port);
 
    if (-1==bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)))
    {
	perror("bind error\n");
	exit(1);
    }
 
    if (-1==listen(listend,5))
    {
	perror("listen error\n");
	exit(1);
    }
 
    while (1)
    {
        if (-1==(connectd=accept(listend,(struct sockaddr*)&client,&len)))
    	{
		perror("create connect socket error\n");
		continue;
    	}
 
	
	sendnum = sprintf(send_buf,"hello,the guest from %s\n",inet_ntoa(client.sin_addr));
    if ( 0 >send(connectd,send_buf,sendnum,0))
	{
		perror("send error\n");
		close(connectd);
		continue;
	}
	
 
    if (0>(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)))
	{
		perror("recv error\n");
		close(connectd);
		continue;
	}
	recv_buf[recvnum]='\0';
 
	printf ("the message from the client is: %s\n",recv_buf);
 
	if (0==strcmp(recv_buf,"quit"))
        {
		perror("the client break the server process\n");
		close(connectd);
		break;
	}
 
	sendnum = sprintf(send_buf,"%s\n",recv_buf);
  
    send(connectd,send_buf,sendnum,0);
  
	close(connectd);
	continue;
   }
    close(listend);
    return 0;
}

client.c

#include<stdlib.h>
#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<string.h>
#include<unistd.h>
#include<netinet/in.h>
#include<arpa/inet.h>
 
#define PORT 8900
 
void print_usage(char * cmd)
{
	fprintf(stderr," %s usage:\n",cmd);
	fprintf(stderr,"%s IP_Addr [port] [ttl]\n",cmd);
 
}
 
 
int main(int argc,char** argv)
{
	struct sockaddr_in server;
	int ret;
	int len;
	int port;
	int sockfd;
	int sendnum;
	int recvnum;
	char send_buf[2048];
	char recv_buf[2048];
    int ttl = 128;
    int yes = 1;
 
	if ((2>argc)|| (argc >4))
	{
		print_usage(argv[0]);
		exit(1);
 
	}
 
    if (3==argc) 
    {
		port = atoi(argv[2]);
    }

    if(4 == argc)
    {
		port = atoi(argv[2]);
        ttl = (char)atoi(argv[3]);
    }
    
    printf("clinet ip = %s port=%d ttl=%d\n",argv[1],port,ttl);
 
    if (-1==(sockfd=socket(AF_INET,SOCK_STREAM,0)))
	{
		perror("can not create socket\n");
		exit(1);
	}

    setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));  //设置组播TTL
    setsockopt(sockfd, IPPROTO_IP, IP_TTL, (char *)&ttl, sizeof(ttl)); //set ttl  on all sockets
    setsockopt(sockfd, IPPROTO_IP, IP_RECVTTL , &yes, sizeof(yes));//Tell me the TTL of incomming packets.

	memset(&server,0,sizeof(struct sockaddr_in));
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = inet_addr(argv[1]);
	server.sin_port = htons(port);
 
	if (0>(ret=connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr))))
	{
		perror("connect error");
		close(sockfd);
		exit(1);
 
	}
 
	printf("what words do  you want to tell to server:\n");
	fgets(send_buf,2048,stdin);
 
	if (0>(len=send(sockfd,send_buf,strlen(send_buf),0)))
	{
		perror("send data error\n");
		close(sockfd);
		exit(1);
 
	}
 
	if (0>(len=recv(sockfd,recv_buf,2048,0)))
	{
		perror("recv data error\n");
		close(sockfd);
		exit(1);
	}
	
	recv_buf[len]='\0';
 
	printf("the message from the server is:%s\n",recv_buf);
	close(sockfd);
 
        printf("GAIA_ACU_VEHICLE_CONFIG = %s\n", getenv("GAIA_ACU_VEHICLE_CONFIG"));
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值