我正在尝试构建服务器客户端代码。客户端可以从服务器下载任何文件,但我有二进制文件的问题
这是我的客户代码:
#include <stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<errno.h>
#include<stdlib.h>
#include<fcntl.h>
#define Max_len 1025
//-------------------------- to replay for pecific secret simpol 0x55
char secret(char * str)
{
char sub=0x55;
if(sub==str[0])
{
sub=0xAA;
return sub;
}
else
{
printf("server does not give the right secret code\n");
exit(0);
}
}
//-------------------------warraper function for perror
void error(char * str)
{
perror(str);
exit(0);
}
int main ( int nof_arg, char **argv)
{
//------------------------define data types
int sockfd,number,portno,val=0,fil_fd; //to store the file descreptore of socket
char rec_lin [Max_len],f_name[20]="\0",car; // act as buffer
struct sockaddr_in servaddr;
char * read_one;
FILE * file_ptr; //------------------------ welcome message identife the writer
printf("\n\t Welcom the client \n\t Name: Eftikhar Emad \n\t ID: 20100175003\n\tsection #1: 9:15-10:15\n\n");
//------------------------ prepair the client to start connection
if (nof_arg < 3) //check the number of entered arregument
error("you need the IP and port number to connect please check them again\n");
portno=atoi(argv[2]); // convert the port from string to int
if((portno<=22000) || (portno>=23000)) //check to see if the port numberif valiled
error("your port number is out of range please try agin start with 22XXX\n");
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0) //socket creation
error("Socket creation error");
bzero(&servaddr,sizeof(servaddr)); //static define for the server
servaddr.sin_family=AF_INET;
servaddr.sin_port = htons(portno);
if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr)<=0)//it can be used to check
error("inet_pton error ");
if((connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr)))<0)//connection
error("connect error");
//------------------------------------start define the server valited
bzero(rec_lin,sizeof(rec_lin));
read(sockfd,rec_lin ,sizeof(rec_lin));
printf("received the byte 0x55 from the server\n"); //will readonly one char
car=secret(rec_lin);
printf("Sending ack 0xAA to the server\n");
bzero(rec_lin,sizeof(rec_lin));
snprintf(rec_lin,sizeof(rec_lin),"%c",car);
write(sockfd,rec_lin,1); //send 0xAA if 0x55
//-------------------------------------print the list from server
read(sockfd,rec_lin,sizeof(rec_lin));
while(rec_lin[0]!= '\0')
{
read(sockfd,rec_lin,sizeof(rec_lin));
printf("%s\n",rec_lin);
}
//-------------------------after know the server start to ask and send file name
printf("enter file name to download : ");
gets(f_name); //rad file name from user
snprintf(rec_lin,sizeof(rec_lin),"%s",f_name);
write(sockfd,rec_lin,sizeof(rec_lin)); //send the file name to server
bzero(rec_lin,sizeof(rec_lin));
//--------------------------------------check server reply 0/1 for finding or not
read(sockfd,rec_lin,/*sizeof(rec_lin)*/1);
int p;
if(rec_lin[0]==0x31) //if file found inform the user,start,ending msg
{ //no creation to file unless it found on server
printf("Received 1 from server %s exists\nStart downloading the file\n",f_name);
fil_fd=open(f_name,O_RDWR| O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
while((val=read(sockfd,rec_lin,sizeof(rec_lin)-1))>0)
{
p=strlen(rec_lin);
// rec_lin[val]='\0';
write(fil_fd,rec_lin,/*sizeof(rec_lin)*/p+1);
bzero(rec_lin,1049);
}
printf("Done Downloadng the file.......exit\n\n");
close(fil_fd);
}
else //if file not found terminate the connection
{
printf("file not found get ... connection will closed\n\n");
}
// -----------------------------terminate connection if it Done in the right way
close(sockfd);
return 0;
}
这是我的服务器代码:
#include<stdio.h>
#include<errno.h>
#include<arpa/inet.h>
#include<string.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<fcntl.h>
#include<netdb.h>
#include<dirent.h>
#define Max_len 1025
void error (char * str)
{
perror(str);
exit(0);
}
int main (int argc, char ** arg)
{
/ /------------------------- define data type
int listenfd,connfd,clilen,portno,fil_fd,n;
char buff[Max_len], *str,f_name[100],car=0xAA,h_IP[30],h_P[20];
struct sockaddr_in servaddr,cliaddr;
DIR * ddir;
struct dirent * ndir;
//------------------------- socket intinalizing
printf("\n\t Welcom the server \n\t Name: Eftikhar Emad \n\t ID: 20100175003\n\t section #1: 9:15-10:15\n");
if(argc != 2) //of user forget to insert the port number
error("missing port number to complet establishment\n");
portno=atoi(arg[1]); //convert the port to int and check if it was within the rang
if((portno<=22000) || (portno>=23000))
error("your port number not valid .... pleas insert one in reng (22000,22999)\n");
listenfd=socket(AF_INET,SOCK_STREAM,0); //creat the listing socket
bzero((char *)&servaddr ,sizeof(servaddr));
servaddr.sin_family=AF_INET; //Ipv4
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
servaddr.sin_port=htons(portno);
bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));//bind the liten socket to specific port
listen(listenfd,5);
//-------------------------- server start to wait to handle requests
for(;;)
{
printf("server wait for connections\n");
bzero((char *)&cliaddr ,sizeof(cliaddr)); //clear the previus client information
clilen=sizeof(cliaddr); //client informaton container
connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
int f=fork(); //start of fork()
if(f==0)
{
close(listenfd);
if(connfd<0)
error("error in accept this connection\n");
//--------------------------------------- //start the secret hand chacking
bzero(buff,sizeof(buff));
getnameinfo((struct sockaddr *)&cliaddr,sizeof(cliaddr),h_IP,sizeof(h_IP),h_P,sizeof(h_P),0);
printf("Sending byte 0x55 to client with IP %s and port of %s\n",h_IP,h_P);
//get the IP AND port# of the client
snprintf(buff,sizeof(buff),"%c",0x55);
write(connfd,buff,sizeof(buff));
//--------------------------------------- //read file name
car=0xAA;
read(connfd,buff,sizeof(buff));
printf("received 0XAA from client \n");
if(car==buff[0])
{
//------- send the list to the client
snprintf(buff,sizeof(buff),"select file to download it\n");
write(connfd,buff,sizeof(buff));
ddir=opendir(".");
if(ddir==NULL)
{printf("error\n");exit(0);}
while((ndir=readdir(ddir))!=NULL)
{//printf("%s\n",ndir->d_name);
snprintf(buff,sizeof(buff),"%s",ndir->d_name);
printf("%s\n",buff);
write(connfd,buff,sizeof(buff));
}
write(connfd,"\0",1);
closedir(ddir);
read(connfd,buff,sizeof(buff)); //get the name after get 0xAA
strncpy(f_name,buff,sizeof(buff)-1);
}
else
{ printf("this is not secure client\n");break;}
//-------------------------------------- if file found send 1 else 0
fil_fd=open(f_name,O_RDONLY); //file opent to be read only
if(fil_fd < 0)
{
snprintf(buff, sizeof(buff),"%d",0);
write(connfd,buff,1);
printf("file is not found\n"); //retminate connection only
break;
}
else
{
snprintf(buff, sizeof(buff),"%d",1);
write(connfd,buff,sizeof(buff));
printf("file exists.Send %s to client\n",buff);
//-----------------------------------reading and sending
while((n=read(fil_fd,buff,sizeof(buff)-1))>0)
{ buff[n]='\0';
write(connfd,buff,/*sizeof(buff)*/n+1); //sending the file process
bzero(buff,sizeof(buff));
}//end of uploading
printf("end download thf file");
close(fil_fd);
}//end of if_else
close(connfd);
exit(0);
}//end of child code
else
{
//wait(NULL);
printf("-------------------------------\n");
close(connfd);
}
}//end of for()
//--------------------------------------------prepair the server connection
close(listenfd);
exit(0);
return 0;
}//main()
如果我将它与“file.txt”一起使用,这段代码可以正常工作。
我希望在不使用fread()
或fwrite
或fopen
的情况下将其与二进制文件一起使用。
有没有办法做到这一点?
答案 0 :(得分:1)
您无法编写忽略read(),recv()等返回值的正确网络软件。这些函数返回-1表示错误,0表示流结束或读取计数。您现在的代码忽略了所有三种可能性,它还假设read()填充缓冲区。没有任何地方可以这么说。
编辑:我应该明确指出,这同样适用于从任何来源阅读,而不仅仅是网络。
答案 1 :(得分:0)
我的问题是......使用open()
将创建文件数据,因此当执行二进制文件时会出现“无法执行二进制文件”。
解决方案:使用fopen(file_name,"r+b")
可以创建以不同于文本文件