📄 ftpnet.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 + -