雨中飞蛾 2017-05-10 14:05 采纳率: 37.5%
浏览 934
已结题

winsock 网络编程 ftp服务器设计

课程设计时我选的课题是【FTP服务器设计与实现】,老师非要用系统自带的那个telnet作为客户端测试
就是用这个命令【telnet ip 端口号】,但是在实现get命令时下载的文件不知道保存到那里去了。
对于put命令实在是一点头绪都没有,求大神指点。。
#include
#include
#pragma comment(lib, "ws2_32.lib")
#define CLIENT_COUNT 2
#include
#include
#include

typedef struct _client_t{
SOCKET c;
SOCKADDR_IN c_sa;
} client_t;

client_t clients[CLIENT_COUNT];

WSADATA wsa_data;
SOCKET s;
SOCKADDR_IN sa;

unsigned short port = 23;
int backlog = SOMAXCONN;//

fd_set readfds;

int client_count = 0;
int r = 0;
char path[80]="shareFile";
char strObject[100]="";
char pathname[80]="";
char buf[80];//接收发送缓冲区
int nn,bytes;
int iSynError=1;

int sdirfun(SOCKET newsocket);//打印文件目录
int sgetfun(SOCKET newsocket,char name[80],int bytes);//下载文件
//int sputfun(SOCKET newsocket,pathname);//发送文件

int main(int argc, char *argv[]) {
if ( 0!=access("shareFile",0))
_mkdir("shareFile");

int n;
int i;

printf("server start...\n");

memset(&wsa_data, 0, sizeof(wsa_data));//地质结构清零
WSAStartup(0x202, &wsa_data);//初始化版本号2.2

printf("socket...\n");
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建套接字
if(INVALID_SOCKET==s) {
    return -1;
}


memset(&sa, 0, sizeof(sa));//地址结构清零
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = INADDR_ANY;
sa.sin_port = htons(port);
if(SOCKET_ERROR==bind(s, (SOCKADDR*)&sa, sizeof(sa))) {//绑定
    r = -2;
    goto clean; 
}

if(SOCKET_ERROR==listen(s, backlog)) {//监听
    r = -3;
    goto clean;
}




while(1) 
{
    FD_ZERO(&readfds);
    FD_SET(s, &readfds);
    for(i=0;i<client_count;i++)
    {
        FD_SET(clients[i].c,&readfds);
    }
    n = select(0,&readfds,NULL,NULL,NULL);
    if(n<0)
    {
        printf("select error.\n");
        r = -4;
        goto clean;
    } else if(n==0) 
    {
        printf("time out\n");
    } else//////此时n表示可以使用的套接字数量 
    {
        if(FD_ISSET(s,&readfds)) //表示有客户连接请求到达(接收后并处理命令)
        {
            SOCKET c;
            SOCKADDR_IN c_sa;
            int c_sa_len = sizeof(c_sa);
            printf("listen message.\n");

            c = accept(s,(struct sockaddr *)&c_sa,&c_sa_len);


            if(INVALID_SOCKET==c)
            {
                printf("accept error.\n");
            }
            else 
            {
                if(client_count>=CLIENT_COUNT) 
                {
                    closesocket(c);
                    printf("client full.\n");
                } else
                { 
                    FD_SET(c, &readfds);
                    clients[client_count].c = c;
                    clients[client_count].c_sa = c_sa;
                    client_count++; 



                    printf("%s 端口已连接: %d \n",inet_ntoa(c_sa.sin_addr), ntohs(sa.sin_port));
                    sprintf(buf,"        *****欢迎使用本服务器**** \r\n");  //向客户端发送欢迎消息
                    send(c, buf, strlen(buf), 0);

                    sprintf(buf,"        dir:   列出远方当前目录\r\n");  //向客户端发送欢迎消息
                    send(c, buf, strlen(buf), 0);

                    sprintf(buf,"        get:   取远方的一个文件\r\n");  //向客户端发送欢迎消息
                    send(c, buf, strlen(buf), 0);

                    sprintf(buf,"        put:   传给远方一个文件\r\n");  //向客户端发送欢迎消息
                    send(c, buf, strlen(buf), 0);


                }
            }
        } 
        else //有客户发来数据
        {
            //int bytes;
            int buf_len = 80;
            int is_need_close = 0;
            printf("\nclient message.\n");
            for(i=0;i<client_count;i++)
            {
                if(FD_ISSET(clients[i].c, &readfds))
                {
                    memset(buf,0,buf_len);
                    bytes = recv(clients[i].c, buf, buf_len, 0);
                    if(bytes<0)
                    {
                        printf("recv error: %d.\n", WSAGetLastError());
                        is_need_close = 1;
                    } else if(bytes==0) {
                        printf("client offline.\n");
                        is_need_close = 1;
                    } else
                    {

                          if(strncmp(buf,"dir",3)==0) sdirfun(clients[i].c);
                          if (strncmp(buf,"get",3)==0)  sgetfun(clients[i].c,buf,bytes); 

                          if (strncmp(buf,"put",3)==0)  
                          {
                            sprintf(buf,"请输入文件路径:\r\n");
                            send(clients[i].c,buf,buf_len,0);

                            recv(clients[i].c, pathname, 80, 0);


                           // sputfun(clients[i].c,pathname); 
                          }

                    }
                    if(is_need_close)
                    {
                        closesocket(clients[i].c);
                        clients[i] = clients[client_count-1];
                        clients[client_count-1].c = INVALID_SOCKET;
                        client_count--;
                    }
                } 
            }
        }
    }
}

clean:
printf("server stop...\n");
if(INVALID_SOCKET!=s) {
closesocket(s);
}
for(i=0;i if(clients[i].c!=0&&clients[i].c!=INVALID_SOCKET) {
closesocket(clients[i].c);
}
}
WSACleanup();
return 0;
}
int sdirfun(SOCKET newsocket)
{
char temp_buffer[80];
FILE *p_FiLeTemp;
strObject[0]='\0';
strcat(strObject,"dir ");
strcat(strObject,path);
strcat(strObject,">tmp.txt");
system(strObject); //system函数执行shell命令
p_FiLeTemp=fopen("tmp.txt","r"); //打开执行结果文件,准备发送到客户端
while (fgets(temp_buffer,80,p_FiLeTemp)!=NULL) //每次读取80字节发送

{

sprintf(buf,"%-81s",temp_buffer); //
send(newsocket, buf, strlen(buf), 0);

}
fclose(p_FiLeTemp); //发送完毕,关闭结果临时文件

system("del tmp.txt"); //删除结果临时文件
printf("客户端命令:dir:已执行 ! \n");
r=0;
return 0;
}

/***********************************************************************
函数名:sgetfun
说明: 用于处理来自客户端的文件下载命令
输入参数: SOCKET h_newsocketet,命令通过此socket接收到,可通过它响应命令。
***********************************************************************/
int sgetfun(SOCKET newsocket,char name[80],int bytes)
{

int i=0,k=0;
char filename[20],temp_buffer[80];
char *p_FileName=strObject;  
FILE *fp;
for(i=0;i<bytes-3;i++)
    if(name[i+4]!='\r')
    filename[i]=name[i+4];

printf("客户端下载文件为:");
puts(filename);
strcat(strObject,filename);
//打开客户端欲下载的文件
if( (fp=fopen(p_FileName,"r")) == NULL )
{ //未成功打开文件
sprintf(buf, "Sorry, cannot open %s. Please try again.\r\n", filename);
bytes = send(newsocket, buf, strlen(buf), 0);
sprintf(buf, "over\r\n");
bytes = send(newsocket, buf, strlen(buf), 0);
return 1;
}
else
{

      printf("文件正在上传:%s\n\n",filename);
      sprintf(buf, "send...\r\n");
      bytes = send(newsocket, buf, strlen(buf), 0);
      while (fgets(temp_buffer,80,fp)!=NULL)
      {    //循环读取文件并通过h_newsocketet发送到客户端
           sprintf(buf,"%s",temp_buffer); 
           send(newsocket, buf, 80, 0);
            // printf("."); //文件发送中,每发80个字节在屏幕打一个点号
      }
      fclose(fp);
      sprintf(buf, "send over\r\n"); 
      bytes = send(newsocket, buf, strlen(buf), 0);
 }        
 //iSynError=0;  
 printf("客户端命令:get:已执行! \n");

 return 0;

}
/*
/********************************************************************
函数名:sputfun
说明: 用于处理来自客户端的文件上传命令
*******************************************************************//*/
int sputfun(SOCKET newsocket,pathname)
{
//printf("Equivalent to put. \n");

    int i=4,k=0;
    char filename[20];
    // identify the filename from rbuffer after the word "RETR "
    while (1)
    {
        bytes = recv(newsocket,&RecvBuffer[i],1,0);
        if ((bytes < 0) || (bytes == 0))
            break;
        filename[k]=RecvBuffer[i];
        if (RecvBuffer[i] == '\0')
        { 
            filename[k] = '\0';
            break; 
        } 
        if (RecvBuffer[i] != '\r')
        {
            i++;
            k++;
        }
     } // end of while 

    strcat(strObject,filename);
    printf("客户端上传文件:%s\n",strObject);
    char *p_FileName=strObject;       
    FILE *fpse;
    if( (fpse=fopen(strObject,"w")) == NULL )
    {
        printf("open errer!\n");
        return 1;   
    }
    else
    {
        printf("已接受文件  : %s\n",filename);

        while(1)
        {
        //读取流并显示
            int ret;
            ret = recv(newsocket, RecvBuffer, 80, 0);
            if (ret == 0)        // Graceful close
                return 0;
            else if (ret == SOCKET_ERROR)
            {
                printf("recv() failed: %d\n", WSAGetLastError());
                return 0;
            }       
            if(strncmp(RecvBuffer,"226 Transfer",strlen("226 Transfer"))==0)
            {
                break;
            }               
            fprintf(fpse,"%s",RecvBuffer);              
        }
        printf("RBUFFER=%s",RecvBuffer);
        fclose(fpse);           
    }   


 iSynError=0;  
 printf("客户端命令:put:已执行! \n");
 return 0;

}
*/


  • 写回答

1条回答 默认 最新

  • threenewbee 2017-05-10 15:53
    关注
    评论

报告相同问题?

悬赏问题

  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 shape_predictor_68_face_landmarks.dat
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料