[buug] A socket program

George Wong crazylion at vip.sina.com
Tue Jul 20 07:23:00 PDT 2004


 
I write a socket program which function is to transmit a file on linux. I but it is always abnormal. There is no transfers occour. I cannot find out reason. Could anybody give me some advices?
The attachment is the exacutable file. 

Problem: 1.Every time,after a client unconnected to the server,server will stop, but it should loop forever untill I poweroff. 2.It could only create a 0 byte file which name is as same as I want, There is acctually no transfers occours.

Usage: ./server -h && ./client -h show help

----server.c------
/*
* server.c
*
* Multiclient supported
*
* Create: 15:43 2004-07-19
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/wait.h>

#ifndef SHUT_RDWR
#define SHUT_RDWR 3
#endif

#define MAX_CLIENTS 64
#define BUF_SIZE 4096
#define BACKLOG 10 /* How many pending connections queue will hold */
#define CORRECT 1
#define WRONG 0

/*
* Client List
*/

typedef struct{
FILE *rece;
FILE *write;
} ClientInfo;

ClientInfo client_list[MAX_CLIENTS];

/*
* Used to report error
* and return to shell
*/
static void bail(const char *on_what)
{
if(errno!=0)
{
fputs(strerror(errno),stderr);
fputs(":",stderr);
}
fputs(on_what,stderr);
fputc('\n',stderr);
exit(1);
}


void help()
{
printf("File server 0.1:\n");
printf("Usage: server [host address [port]]\n");
printf("Examples:\n");
printf("\t server\n");
printf("\t server 127.0.0.1\n");
printf("\t server 127.0.0.1 9090\n");
printf("\t server -h\n");
printf("\n\nFor bug report, please mail to crazylion at vip.sina.com\n");
}



/* 
* Check if the format of host and port is right
*/ 
int check(char *host,char *port)
{
int index=0; /* Arrary subscript */
while(host[index]!='\0') /* Check validity of host address */
{
if(isdigit(host[index])||host[index]=='.')
;
else
{
printf("Please check host format, such as 127.0.0.1 \n or type -h for help.\n");
return WRONG;
break;
}
index++;
}
if(isdigit(*port)) /* Check validity of port number */
;
else
{
printf("Please check port format, such as 9090 \n or type -h for help.\n");
return WRONG;
}
return CORRECT;
}



/*
* Client process function
*/
static int process_client(int n,int srv)
{
char filename[50];
char buffer[BUF_SIZE];
int z;
FILE *rece=client_list[n].rece;
FILE *write=client_list[n].write;
FILE *fd;


/*
* Get filename
*/ 
z=recv(srv,filename,sizeof filename,0);
if(z==-1)
bail("recv(2)");
printf("The file name is %s",filename);

if((fd=fopen(filename,"r"))==NULL)
bail("fopen(3)");

rewind(fd);
while(!feof(fd) && (z=fread(buffer,sizeof buffer,1,fd))>0)
{
fwrite(buffer,sizeof buffer,1,write);
}
printf("\n\n\t\tFile transfers succeed!\n");
fclose(fd);
/*
* Close client connection
*/
fclose(write);
shutdown(fileno(rece),SHUT_RDWR);
fclose(rece);
client_list[n].rece=client_list[n].write=NULL;

return EOF; 
}

/*
* Main program
*/
int main(int argc,char **argv)
{
int z;
char *server_addr="127.0.0.1";
char *server_port="9090";
//char filename[50];
struct sockaddr_in addr_server; /* AF_INET */
struct sockaddr_in addr_client; /* AF_INET */
int len_inet; /* Length */
int server=-1; /* Server socket */
int client=-1; /* Client socket */
int ret_val; /* Return value of fuction select(2)*/
int max; /* max fd+1 */
fd_set rece_set; /* Reading file descriptor set */
fd_set work_set; /* Working set */
struct timeval tv; /* Timeout value */

/*
* Initialize client structure:
*/
for(z=0;z<MAX_CLIENTS;z++)
{
client_list[z].rece=NULL;
client_list[z].write=NULL;
}

/*
* Using address provided by command line
* or using default address 127.0.0.1
*/
if(argc>=2)
{
if(!strcmp(argv[1],"-h"))
{
help();
return 1;
}
else
{
server_addr=argv[1];
if(argc>=3)
server_port=argv[2];
}
}
if(check(server_addr,server_port)==CORRECT)
;
else
return WRONG;



/*
* Create a TCP/IP socket to use
*/
server=socket(PF_INET,SOCK_STREAM,0);
if(server==-1)
bail("socket(2)");

/*
* Initialize address structure
*/
memset(&addr_server,0,sizeof addr_server);
addr_server.sin_family=AF_INET;
addr_server.sin_port=htons(atoi(server_port));
addr_server.sin_addr.s_addr=inet_addr(server_addr); 

/*
* Bind the server address
*/
len_inet=sizeof addr_server;
z=bind(server,(struct sockaddr *)&addr_server,len_inet);
if(z==-1)
bail("bind(2)");

/*
* Make it a listening socket
*/
z=listen(server,BACKLOG);
if(z==-1)
bail("listen(2)");

/*
* Express interest in socket
* server for read events
*/
FD_ZERO(&rece_set); /* Init */
FD_SET(server,&rece_set); /* Add server socket */
max=server+1; /* max fd+1 */

/*
* Begin server loop
*/
while(1)
{
/*
* Copy rece_set to work_set
*/
FD_ZERO(&work_set);
for(z=0;z<max;z++)
{
if(FD_ISSET(z,&rece_set))
FD_SET(z,&work_set);
}

/*
* Sample timeout of 1.5 seconds:
*/
tv.tv_sec=1;
tv.tv_usec=500000;

ret_val=select(max,&work_set,NULL,NULL,&tv);
if(ret_val==-1)
{
fprintf(stderr,"%s:select(2)\n",strerror(errno));
exit(1);
}else if(!ret_val){
/* Time out */
continue;
}

/*
* Check if a connect has ocuured
*/
if(FD_ISSET(server,&work_set))
{
/*
* Waiting for connect
*/
len_inet=sizeof addr_client;
client=accept(server,(struct sockaddr *)&addr_client,&len_inet);
if(client==-1)
bail("accept(2)");

/*
* See if we've exceeded server
* capacity. If so colse the socket
* and wait for the next event
*/
if(client>=MAX_CLIENTS)
{
close(client); /* At capacity */
continue;
}

/*
* Create streams
*/
client_list[client].rece=fdopen(client,"r");
if(!client_list[client].rece)
{
close(client); /* Failed */
continue;
}

client_list[client].write=fdopen(dup(client),"w");
if(!client_list[client].write)
{ 
fclose(client_list[client].rece);
continue;
}

if(client+1>max)
max=client+1;

/*
* Set read/write streams
*/
setvbuf(client_list[client].rece,NULL,_IOFBF,BUFSIZ);
setvbuf(client_list[client].write,NULL,_IOFBF,BUFSIZ); 

/*
* Check client action
*/
for(client=0;client<max;client++)
{
if(client==server)
continue; /* Not server */
if(FD_ISSET(client,&work_set))
{
if(process_client(client,server)==EOF)
{
FD_CLR(client,&rece_set);
}
}
}

/*
* Reduce max if we are able to
*/
for(client=max-1;client>=0 && !FD_ISSET(client,&rece_set);client=max-1)
max=client;
}

return 0;
}
}

----client.c-----
/*
* client.c
*
* Send request to server
*
* Create: 10:42 2004-07-19
*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/wait.h>



#define BUF_SIZE 4096
#define CORRECT 1
#define WRONG 0

/*
* Used to report errors
* and return to shell
*/
static void bail(const char *on_what)
{
fputs(strerror(errno),stderr);
fputs(";",stderr);
fputs(on_what,stderr);
fputc('\n',stderr);
exit(1);
}


/* 
* Check if the format of host and port is right
*/ 
int check(char *host,char *port)
{
int index=0; /* Arrary subscript */
while(host[index]!='\0') /* Check validity of host address */
{
if(isdigit(host[index])||host[index]=='.')
;
else
{
printf("Please check host format, such as 127.0.0.1 \n or type -h for help.\n");
return WRONG;
break;
}
index++;
}
if(isdigit(*port)) /* Check validity of port number */
;
else
{
printf("Please check port format, such as 9090 \n or type -h for help.\n");
return WRONG;
}
return CORRECT;
}


void help()
{
printf("File server 0.1:\n");
printf("Usage: client [host address [port]]\n");
printf("Examples:\n");
printf("\t client\n");
printf("\t client 127.0.0.1\n");
printf("\t client 127.0.0.1 9090\n");
printf("\t client -h\n");
printf("\n\nFor bug report, please mail to crazylion at vip.sina.com\n");
}


int main(int argc,char **argv)
{
int z;
char *server_addr="127.0.0.1";
char *server_port="9090";
char filename[50];
char *buffer[BUF_SIZE];
struct sockaddr_in addr_server;
int len_inet;
int sock;
FILE *write;
FILE *rece;
FILE *fd;


/*
* Using address provided by command line
* or using default address 127.0.0.1
*/
if(argc>=2)
{
if(!strcmp(argv[1],"-h"))
{
help();
return 1;
}
else
{
server_addr=argv[1];
if(argc>=3)
server_port=argv[2];
}
}
if(check(server_addr,server_port)==CORRECT)
;
else
return WRONG;

/*
* Create a TCP/IP socket to use
*/
sock=socket(PF_INET,SOCK_STREAM,0);
if(sock==-1)
bail("socket(2)");

/*
* Setup server socket address
*/
memset(&addr_server,0,sizeof addr_server);
addr_server.sin_family=AF_INET;
addr_server.sin_port=htons(atoi(server_port));
addr_server.sin_addr.s_addr=inet_addr(server_addr);
if(addr_server.sin_addr.s_addr==INADDR_NONE)
bail("bad address");

len_inet=sizeof addr_server;

/*
* Connect to the server
*/
z=connect(sock,&addr_server,len_inet);
if(z==-1)
bail("connect(2)");

printf("Please enter filename which you want to transmit: ");
scanf("%s",filename);
z=send(sock,filename,sizeof filename,0);
if(z==-1)
bail("sent(2)"); 
/*
* Create streams
*/
rece=fdopen(sock,"r");
if(!rece)
{
close(sock); /* Failed */
//continue;
}

write=fdopen(dup(sock),"w");
if(!write)
{ 
fclose(rece);
//continue;
}

/*
* Set read/write streams
*/
setvbuf(rece,NULL,_IOFBF,BUFSIZ);
setvbuf(write,NULL,_IOFBF,BUFSIZ);


if((fd=fopen(filename,"w"))==NULL)
bail("fopen(3)");

while(fread(buffer,sizeof buffer,1,rece)>0)
{
fwrite(buffer,sizeof buffer,1,fd);
}

printf("\n\tFile transfers succeed!\n");
fclose(fd);

/*
* Close client connection
*/
fclose(write);
shutdown(fileno(rece),SHUT_RDWR);
fclose(rece);

return 0;
} 






More information about the buug mailing list