⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpnet.c

📁 模拟linux平台下边的vsFtp服务器可以实现文件的断点续传和下载
💻 C
字号:
#include "ftpnet.h"
#include "ftppub.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h> 
#include <net/if.h> 
#include <net/if_arp.h>
#include <signal.h>
#include <errno.h>

#define inaddrr( A ) ( *(struct in_addr*) &ifr->A[sizeof(sa.sin_port)] ) 
#define IFRSIZE      ((int)(size *sizeof(struct ifreq)))

//循环读取,作用就是防止在读取过程中被中断打断,当被中断打断后read函数会返回IENTR错误
int read_loop(int fd,char *buf,int size)
{
	int num_read=0;
	int retval;
	while (1)
	{
		retval=read(fd,buf+num_read,size);
		if (retval<0)
		{
			if (errno==EINTR)
				continue;
			else
				return retval;
		}
		else if (retval==0)
		{
			return num_read;
		}
		num_read+=retval;
		size-=retval;
		if (size==0)
		{
			return num_read;
		}
	}
}
//循环写入,作用就是防止在读取过程中被中断打断,当被中断打断后write函数会返回IENTR错误
int write_loop(int fd,char *buf,int size)
{
	int retval;
	int num_written=0;
	while (1)
	{
		retval=write(fd,buf+num_written,size);
		if (retval<0)
		{
			if (errno==EINTR)
				continue;
			else
				return retval;
		}
		else if (retval==0)
		{
			return num_written;
		}
		num_written+=retval;
		size-=retval;
		if (size==0)
		{
			return num_written;
		}
	}
}





//建立一个套接字
int CreateSocket()
{
	int sockfd;
	sockfd=socket(AF_INET, SOCK_STREAM, 0);
	return sockfd;
}
//初始化套接字地址
void init_socket_addr(struct sockaddr_in *sock_addr,char * ip_address,int port)
{
	sock_addr->sin_family=AF_INET;//设定套接字地址的地址簇(即套接字的通信区域)
	if(ip_address==NULL)
	{
		//printf("初始化所有IP地址\n");
		(sock_addr->sin_addr).s_addr = htonl(INADDR_ANY);//INADDR_ANY代表的本地的所有IP地址
	}
	else
	{
		//printf("指定IP地址\n");
		inet_aton(ip_address,&(sock_addr->sin_addr));//inet_aton函数将点分十进制IP地址转换成32位无符号的整型IP地址
	}
	sock_addr->sin_port = port ? htons(port):0;//将本地字节序转换成网络字节序 网络字节序是大端 即高字节存放高地址,低字节存放低地址
}

//监听套接字
int listen_socket(int socket,int max_connect_num)
{
	int m;
	m=listen(socket,max_connect_num);//listen的第二个参数是指定同一时刻最多接收多少个用户请求
	return m;
}

//绑定套接字
int bind_socket(int socket,struct sockaddr_in *addr)
{
	int opt=1;
	int m;
	//在setsockopt函数中设置socket选项,SOL_SOCKET参数是SO_REUSEADDR选项所在的组名,SO_REUSEADDR选项在这里的作用是设置套接字地址可以重复使用(即程序非法或正常退出后还可再重复使用套接字地址)
	setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt));
	m=bind(socket,(struct sockaddr *)addr,sizeof(* addr));
	return m;
}

//接收客户端请求
int accept_socket(int socket,struct sockaddr_in *addr)
{
	int connfd;
	socklen_t len;//存放套接字地址长度
	//len=sizeof(* addr);
	connfd=accept(socket,(struct sockaddr *)addr,&len);//
	return connfd;
}
//连接套接字
int connect_socket(int socket,struct sockaddr_in *addr)
{
	int m;
	m=connect(socket,(struct sockaddr *)addr,sizeof(* addr));
	return m;
}


int my_read(int socket,char * buff,int len)
{
	int length;
	//memset(buff,0,sizeof(*buff));//将缓冲区清0

	if(read(socket,buff,len)<=0)
	{
		exit(1);
	}
	length=strlen(buff);

// 	if(strlen(buff)<3)
// 	{
// 		printf("empty info error\n");
// 		Respond(500,"Receve Unknown command.");
// 		return -1;
// 	}
	if(buff[length-2]=='\r' && buff[length-1]=='\n')
	{
		buff[length-2]='\0';
	}
//	printf("my_read的结果是 %s \n",buff);
	return 1;
}


int net_get_local_ip(char *ip_addr) 
{ 
	memset(ip_addr,'\0',sizeof(ip_addr));
    //unsigned char *    u;
	int                sockfd, size = 1;
	struct ifreq *     ifr;
	struct ifconf      ifc;
	struct sockaddr_in sa;
	if (0>(sockfd=socket( AF_INET, SOCK_DGRAM, IPPROTO_IP))) 
    { 
        fprintf( stderr, "Cannot open socket.\n"); 
        exit( EXIT_FAILURE ); 
    } 
    ifc.ifc_req = NULL; 
    do 
    { 
        ++size; 
        if (NULL==(ifc.ifc_req=realloc(ifc.ifc_req, IFRSIZE))) 
        { 
            fprintf(stderr,"Out of memory.\n"); 
            exit(EXIT_FAILURE); 
        } 
        ifc.ifc_len = IFRSIZE; 
        if (ioctl(sockfd, SIOCGIFCONF,&ifc)) 
        { 
            perror( "ioctlSIOCFIFCONF" ); 
            exit( EXIT_FAILURE ); 
        } 
    } while (IFRSIZE <= ifc.ifc_len); 
    ifr = ifc.ifc_req; 
    for (;(char*)ifr <(char*)ifc.ifc_req + ifc.ifc_len;++ifr) 
    { 
        if (ifr->ifr_addr.sa_data == (ifr + 1)->ifr_addr.sa_data) 
        {
            continue; 
        }
        if (ioctl(sockfd,SIOCGIFFLAGS, ifr ) ) 
        { 
            continue; 
        } 
        //printf( "Interface:  %s\n", ifr->ifr_name );
        sprintf(ip_addr,"%s",inet_ntoa( inaddrr( ifr_addr.sa_data ) ) );
        //printf( "IP Address: %s\n", inet_ntoa( inaddrr( ifr_addr.sa_data ) ) ); 
        if ( 0 == ioctl( sockfd, SIOCGIFNETMASK, ifr ) && 
			strcmp( "255.255.255.255", inet_ntoa( inaddrr( ifr_addr.sa_data ) ) ) ) 
        { 
            //printf( "Netmask:    %s\n", inet_ntoa( inaddrr( ifr_addr.sa_data ) ) ); 
        } 
        if ( ifr->ifr_flags & IFF_BROADCAST )
        { 
            if ( 0 == ioctl( sockfd, SIOCGIFBRDADDR, ifr ) && 
				strcmp( "0.0.0.0", inet_ntoa( inaddrr( ifr_addr.sa_data ) ) ) ) 
            { 
                //printf( "Broadcast:  %s\n", inet_ntoa( inaddrr( ifr_addr.sa_data ) ) ); 
            }
        } 
        //printf( "\n" ); 
    }
    close( sockfd );
    return( EXIT_SUCCESS );
}


int Is_Time_Out(int fd, int sec)//传入fd,判断sec时间内是否超时,没超时返回1,超时返回0,错误返回-1
{
	fd_set rset;
	struct timeval tv;
	FD_ZERO(&rset);
	FD_SET(fd,&rset);
	tv.tv_sec=sec;
	tv.tv_usec=0;
	return (select(fd+1,&rset,NULL,NULL,&tv));
}











⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -