/********************************************
** PROGRAM: TcpSer.c **
** AUTHOR: Megan **
** WRITE DATE: 02/03/2001 **
** LAST MODITY DATE: 04/04/2001 **
** COMMENT: FTP服务器 V1.00 **
** 实现客户发出请求下载服务端文件的功能 **
** 服务器能同时响应多个客户的请求 **
**编译方式: cc TcpSer.c -o TcpSer -lsocket **
********************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define S_OWN_PORT 5000
#define BUF_LEN 32765
#define FALSE 0
#define TRUE 1
/* 定义全局变量 */
int _nQuit; //退出标志
/* 函数说明 */
int Putdata(int socketsd); //处理文件传送过程
int Quitset(int sig); //设置退出标志
/* 服务器端主程序 */
int main(void)
{
struct sockaddr_in ser_addr;
// struct sockaddr cli_addr;
int nServersd,nNewsocket;
pid_t pid;
_nQuit = FALSE;
signal(SIGQUIT,Quitset); //等待中断信号
//第一步创建套接字
if ( ( nServersd = socket(AF_INET,SOCK_STREAM,0) ) < 0 )
{
fprintf(stderr,"\nCreate socket failed\n");
return (-1);
}
//第二步初使化服务器端地址
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(S_OWN_PORT);
ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//第三步绑定套接字
if (bind(nServersd,(struct sockaddr*)&ser_addr,sizeof(ser_addr)) < 0)
{
fprintf(stderr,"\nbind failed.\n");
close(nServersd);
return -1;
}
//第四步监听客户请求
listen(nServersd,5);
system("clear");
fprintf(stderr, "\n等待客户请求....\n");
while(_nQuit==FALSE)
{
//第五步接受客户请求
if ((nNewsocket = accept(nServersd,0,0)) < 0)
{
fprintf(stderr,"Accept failed \n");
close(nServersd);
return -1;
}
//第六步创建子进程处理客户请求
if ((pid=fork()) ==0)
{
close(nServersd);
if (Putdata(nNewsocket) <0) //传送文件
{
fprintf(stderr,"\n处理过程出错\n");
close(nNewsocket);
return -1;
}
return (0);
}
if (pid > 0)
{
close(nNewsocket);
}
else
{
fprintf(stderr,"\n创建进程出错....,继续接收别的客户请求\n");
close(nNewsocket);
//此处是否应该关闭服务器端套接字 close(nServersd);
}
}
close(nServersd);
return 0;
}
/*
* Putdata() -- 处理文件传送
* int socketsd -- 客户端 SOCKET 套接字
* return -- -1: 失败 -2: 打开文件失败 0: 成功
*/
int Putdata(int socketsd)
{
FILE* fp;
char sSerbuf[BUF_LEN]; //传送数据缓冲区
int nLen;
memset(sSerbuf,0,BUF_LEN);
//第一步取文件名
nLen = read(socketsd,sSerbuf,sizeof(sSerbuf));
if (nLen == -1)
{
fprintf(stderr,"\nGet Filename Message failed\n");
return (-1);
}
printf("Get Filename:%s success\n",sSerbuf);
if ( !stat(sSerbuf) ) //测试文件是否存在
return (-1);
//第二步打开文件
if ((fp = fopen(sSerbuf,"rb")) == NULL)
{
fprintf(stderr,"open File %s fail\n",sSerbuf);
return (-2);
}
printf("开始传送文件 %s .....\n",sSerbuf);
memset(sSerbuf,0,BUF_LEN);
//读取源文件并发送
//while (!feof(fp))
while ( 1 )
{
//nLen = fread(sSerbuf,sizeof(sSerbuf),1,fp);
nLen = fread(sSerbuf, 1, BUF_LEN, fp);
if (ferror(fp))
{
printf("\n fread file error\n");
fclose(fp);
close(socketsd);
return -1;
}
if ( nLen < 0 )
{
fclose(fp);
close(socketsd);
return -1;
}
if ( nLen == 0 )
{
fclose(fp);
close(socketsd);
break;
}
//if (write(socketsd,sSerbuf,strlen(sSerbuf)) <0)
if ( write( socketsd, sSerbuf, nLen ) < 0 )
{
printf("write error!\n");
close(socketsd);
fclose(fp);
return (-1);
}
memset(sSerbuf,0,BUF_LEN);
}
printf("\n文件传送完毕.\n");
fclose(fp);
close(socketsd);
return 0;
}
/*
* Quitset() -- 设置退出标志
*
* return
*
*/
int Quitset(int sig)
{
printf("\nGet signal SIGINT, force quit server\n");
fflush(stderr);
_nQuit = TRUE;
return 0;
}
/********************************************
** PROGRAM: TcpSer.c **
** AUTHOR: LYC **
** COMMENT: FTP服务器 V1.00 **
** 实现客户发出请求下载服务端文件的功能 **
** 服务器能同时响应多个客户的请求 **
**编译方式: cc TcpSer.c -o TcpSer -lsocket **
********************************************/
评论0