课程设计时我选的课题是【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;
}
*/