操作系统:Ubuntu 12.04 LTS

开发工具:GNU4.6.3,C/C++标准库,Qt4,Qt Creator Documentation 2.4.1

码云:传送门,GitHub:传送门

相关知识点参考:

网络通信TCP/UDP——学习笔记Qt相关知识(二)——学习笔记

C语言无界面版本:

直接上效果

接下来操作和ftp基本操作一致

我一共分了3个文件

我们简单看下代码

ftpclient.c

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <unistd.h>
  4 #include <termios.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <sys/stat.h>
  9 #include <stdlib.h>
 10 #include "network.h"
 11 
 12 NetWork* nw;
 13 NetWork* data_nw;
 14 int list_len = 0;
 15 char buf[256] = {};
 16 
 17 typedef struct List
 18 {
 19     char filename[40];
 20 }List;
 21 
 22 void ex(void);
 23 void must(void);
 24 void ls(void);
 25 void cd_to(char* cd);
 26 void download(char* get);
 27 void upload(char* put);
 28 
 29 int main(int argc,char* argv[])
 30 {    
 31 
 32     char c_ip[40] = {};
 33     strcpy(c_ip,argv[1]);
 34 
 35     nw = open_network('c',SOCK_STREAM,c_ip,21);
 36     if(NULL == nw)
 37     {
 38         printf("open network socket null!\n");
 39         return -1;
 40     }
 41 
 42     printf("Connected to %s.\n",c_ip);
 43 
 44     nrecv(nw,buf,sizeof(buf));
 45     printf("%s",buf);//220
 46 
 47     for(;;)
 48     {
 49         char user[20] = {};
 50         printf("Name (%s:zhizhen):",c_ip);
 51         gets(user);
 52 
 53         sprintf(buf,"USER %s\n",user);
 54         nsend(nw,buf,strlen(buf));
 55 
 56         bzero(buf,sizeof(buf));
 57         nrecv(nw,buf,sizeof(buf));
 58         printf("%s",buf);//331
 59 
 60         char pw[20] = {};
 61         printf("Password:");
 62         struct termios old, new; 
 63         tcgetattr(0, &old);  // 获取终端属性
 64         new = old;    
 65         new.c_lflag &= ~(ECHO | ICANON);// 不使用标准的输出,不显示字符。 
 66          tcsetattr(0, TCSANOW, &new);// 设置终端新的属性
 67         gets(pw);                                
 68         tcsetattr(0, TCSANOW, &old);
 69 
 70         sprintf(buf,"PASS %s\n",pw);
 71         nsend(nw,buf,strlen(buf));//pw
 72 
 73         bzero(buf,sizeof(buf));
 74         nrecv(nw,buf,sizeof(buf));
 75         printf("\n%s",buf);//230
 76         if(strstr(buf,"530") == NULL)
 77         {
 78             break;
 79         }
 80     }
 81 
 82     printf("Remote system type is UNIX.\n");
 83     printf("Using binary mode to transfer files.\n");
 84     
 85     ex();
 86     must();
 87     char cmd[40] = {};
 88     while(1)
 89     {
 90 
 91         printf("ftp> ");
 92         gets(cmd);
 93         if(strcmp(cmd,"bye")==0)
 94         {
 95             break;
 96         }
 97         if(strcmp(cmd,"ls")==0)
 98         {
 99             ls();
100         }
101 
102         char *cmd1 = malloc(20);
103         char *path = malloc(100);
104         sscanf(cmd,"%s %s",cmd1,path);
105         if(strcmp(cmd1,"cd") == 0)
106         {
107             cd_to(path);
108         }
109 
110         if(strcmp(cmd1,"get") == 0)
111         {
112             download(path);
113         }
114 
115         if(strcmp(cmd1,"put") == 0)
116         {
117             upload(path);
118         }
119         
120         //must();
121     }
122 
123     printf("221 Goodbye.\n");//221
124 
125 
126 }
127 
128 void ex(void)
129 {
130     sprintf(buf,"SYST\n");
131     nsend(nw,buf,strlen(buf));
132 
133     bzero(buf,sizeof(buf));
134     nrecv(nw,buf,sizeof(buf));
135     //puts(buf);
136 
137     sprintf(buf,"OPTS UTF8 ON\n");
138     nsend(nw,buf,strlen(buf));
139 
140     bzero(buf,sizeof(buf));
141     nrecv(nw,buf,sizeof(buf));
142     //puts(buf);
143     
144 }
145 
146 void must(void)
147 {
148     sprintf(buf,"PWD\n");
149     nsend(nw,buf,strlen(buf));
150 
151     bzero(buf,sizeof(buf));
152     nrecv(nw,buf,sizeof(buf));
153     //puts(buf);//257
154 
155     sprintf(buf,"PASV\n");
156     nsend(nw,buf,strlen(buf));
157 
158     bzero(buf,sizeof(buf));
159     nrecv(nw,buf,sizeof(buf));
160     //puts(buf);//227
161 
162     unsigned char ip1,ip2,ip3,ip4,port1,port2;
163     sscanf(strchr(buf,'(')+1,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
164     sprintf(buf,"%hhu.%hhu.%hhu.%hhu",ip1,ip2,ip3,ip4);
165     
166 
167     NetWork* data_nw = open_network('c',SOCK_STREAM,buf,port1*256+port2);
168     //printf("connect success fd = %d\n",data_nw->fd);
169     
170     sprintf(buf,"LIST -al\n");
171     nsend(nw,buf,strlen(buf));
172 
173     bzero(buf,sizeof(buf));
174     nrecv(nw,buf,sizeof(buf));
175     //printf("%s",buf);//150
176     
177     int ret = 0;
178     bzero(buf,sizeof(buf));
179     while(ret = nrecv(data_nw,buf,sizeof(buf)))
180     {
181         //printf("%s",buf);
182         bzero(buf,sizeof(buf));
183     }
184     close_network(data_nw);
185 
186     bzero(buf,sizeof(buf));
187     nrecv(nw,buf,sizeof(buf));
188     //printf("%s",buf);//226
189 }
190 
191 void ls(void)
192 {
193     sprintf(buf,"PWD\n");
194     nsend(nw,buf,strlen(buf));
195 
196     bzero(buf,sizeof(buf));
197     nrecv(nw,buf,sizeof(buf));
198     //puts(buf);//257
199 
200     sprintf(buf,"PASV\n");
201     nsend(nw,buf,strlen(buf));
202 
203     bzero(buf,sizeof(buf));
204     nrecv(nw,buf,sizeof(buf));
205     //puts(buf);//227
206 
207     unsigned char ip1,ip2,ip3,ip4,port1,port2;
208     sscanf(strchr(buf,'(')+1,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
209     sprintf(buf,"%hhu.%hhu.%hhu.%hhu",ip1,ip2,ip3,ip4);
210     
211 
212     NetWork* data_nw = open_network('c',SOCK_STREAM,buf,port1*256+port2);
213     //printf("connect success fd = %d\n",data_nw->fd);
214     
215     sprintf(buf,"LIST -al\n");
216     nsend(nw,buf,strlen(buf));
217 
218     printf("200 PORT command successful. Consider using PASV.\n");
219 
220     bzero(buf,sizeof(buf));
221     nrecv(nw,buf,sizeof(buf));
222     printf("%s",buf);//150
223     
224     int ret = 0;
225     bzero(buf,sizeof(buf));
226     while(ret = nrecv(data_nw,buf,sizeof(buf)))
227     {
228         printf("%s",buf);
229         bzero(buf,sizeof(buf));
230     }
231     close_network(data_nw);
232 
233     bzero(buf,sizeof(buf));
234     nrecv(nw,buf,sizeof(buf));
235     printf("%s",buf);//226
236 }
237 
238 void cd_to(char* cd)
239 {
240     char *dir = cd;
241     if(strcmp(dir,"..")==0)
242     {
243         sprintf(buf,"CDUP %s\n",dir);
244     }
245     else
246     {
247         sprintf(buf,"CWD %s\n",dir);
248     }
249     nsend(nw,buf,strlen(buf));
250 
251     bzero(buf,sizeof(buf));
252     nrecv(nw,buf,sizeof(buf));
253     printf("%s",buf);//250
254 }
255 
256 void download(char* get)
257 {
258     char *filename = get;
259     sprintf(buf,"TYPE A\n");
260     nsend(nw,buf,strlen(buf));
261 
262     bzero(buf,sizeof(buf));
263     nrecv(nw,buf,sizeof(buf));
264     puts(buf);
265 
266     sprintf(buf,"SIZE %s\n",filename);
267     nsend(nw,buf,strlen(buf));
268 
269     bzero(buf,sizeof(buf));
270     nrecv(nw,buf,sizeof(buf));
271     puts(buf);
272 
273     sprintf(buf,"MDTM %s\n",filename);
274     nsend(nw,buf,strlen(buf));
275 
276     bzero(buf,sizeof(buf));
277     nrecv(nw,buf,sizeof(buf));
278     puts(buf);
279 
280     sprintf(buf,"PASV\n");
281     nsend(nw,buf,strlen(buf));
282 
283     bzero(buf,sizeof(buf));
284     nrecv(nw,buf,sizeof(buf));
285     puts(buf);
286     
287     unsigned char ip1,ip2,ip3,ip4,port1,port2;
288     sscanf(strchr(buf,'(')+1,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
289     sprintf(buf,"%hhu.%hhu.%hhu.%hhu",ip1,ip2,ip3,ip4);
290 
291     data_nw = open_network('c',SOCK_STREAM,buf,port1*256+port2);
292     printf("connect success fd = %d\n",data_nw->fd);
293 
294     sprintf(buf,"RETR %s\n",filename);
295     nsend(nw,buf,strlen(buf));
296 
297     bzero(buf,sizeof(buf));
298     nrecv(nw,buf,sizeof(buf));
299     puts(buf);
300 
301     int fd = open(filename,O_WRONLY|O_CREAT|O_TRUNC,0644);
302     if(0 > fd)
303     {
304         perror("open");
305         return;
306     }
307     int ret = 0;
308     while(ret = nrecv(data_nw,buf,sizeof(buf)))
309     {
310         write(fd,buf,ret);
311     }
312     close(fd);
313 }
314 
315 void upload(char* put)
316 {
317     char *filename = put;
318 
319     sprintf(buf,"TYPE A\n");
320     nsend(nw,buf,strlen(buf));
321 
322     bzero(buf,sizeof(buf));
323     nrecv(nw,buf,sizeof(buf));
324     puts(buf);
325 
326     sprintf(buf,"SIZE %s\n",filename);
327     nsend(nw,buf,strlen(buf));
328 
329     bzero(buf,sizeof(buf));
330     nrecv(nw,buf,sizeof(buf));
331     puts(buf);
332 
333     sprintf(buf,"PASV\n");
334     nsend(nw,buf,strlen(buf));
335 
336     bzero(buf,sizeof(buf));
337     nrecv(nw,buf,sizeof(buf));
338     puts(buf);
339 
340     unsigned char ip1,ip2,ip3,ip4,port1,port2;
341     sscanf(strchr(buf,'(')+1,"%hhu,%hhu,%hhu,%hhu,%hhu,%hhu",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
342     sprintf(buf,"%hhu.%hhu.%hhu.%hhu",ip1,ip2,ip3,ip4);
343 
344     data_nw = open_network('c',SOCK_STREAM,buf,port1*256+port2);
345     printf("connect success fd = %d\n",data_nw->fd);
346 
347     sprintf(buf,"STOR %s\n",filename);
348     nsend(nw,buf,strlen(buf));
349 
350     int fd = open(filename,O_RDONLY,0644);
351     if(0 > fd)
352     {
353         perror("open");
354         return;
355     }
356     int ret = 0;
357     bzero(buf,sizeof(buf));
358     while(read(fd,buf,1))
359     {
360         nsend(data_nw,buf,strlen(buf));
361         bzero(buf,sizeof(buf));
362     }
363 
364     close_network(data_nw);
365 
366     bzero(buf,sizeof(buf));
367     nrecv(nw,buf,sizeof(buf));
368     printf("%s",buf);// 150-226
369     
370     sprintf(buf,"MDTM %s\n",filename);
371     nsend(nw,buf,strlen(buf));
372 
373 
374     bzero(buf,sizeof(buf));
375     nrecv(nw,buf,sizeof(buf));
376     puts(buf);
377 
378 }

 

network.h

 1 #ifndef NETWORK_H
 2 #define NETWORK_H
 3 #include <netinet/in.h>
 4 #include <stdint.h>
 5 
 6 typedef struct sockaddr* SP;
 7 
 8 typedef struct NetWork
 9 {
10     int fd;            // socket描述符
11     int type;        // 协议类型 SOCK_STREAM/SOCK_DGRAM
12     socklen_t len;     // 地址长度
13     struct sockaddr_in addr; // 通信地址
14 }NetWork;
15 
16 // 创建网络连接
17 NetWork* open_network(char c_or_s,int type,char* ip,uint16_t port);
18 
19 // TCP的server专用
20 NetWork* accept_network(NetWork* nw);
21 
22 // 发送数据
23 int nsend(NetWork* nw,void* buf,uint32_t len);
24 
25 // 接收数据
26 int nrecv(NetWork* nw,void* buf,uint32_t len);
27 
28 // 关闭网络连接
29 void close_network(NetWork* nw);
30 
31 #endif//NETWORK_H

 

network.c

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <arpa/inet.h>
  5 #include <sys/types.h>
  6 #include <sys/socket.h>
  7 #include "network.h"
  8 
  9 // 创建网络连接
 10 NetWork* open_network(char c_or_s,int type,char* ip,uint16_t port)
 11 {
 12     // 在堆上创建NetWork结构
 13     NetWork* nw = malloc(sizeof(NetWork));
 14     if(NULL == nw)
 15     {
 16         perror("network malloc");
 17         return NULL;
 18     }
 19 
 20     // 创建socket对象
 21     nw->fd = socket(AF_INET,type,0);
 22     if(0 > nw->fd)
 23     {
 24         perror("network socket");
 25         free(nw);
 26         return NULL;
 27     }
 28 
 29     // 准备通信地址
 30     nw->addr.sin_family = AF_INET;
 31     nw->addr.sin_port = htons(port);
 32     nw->addr.sin_addr.s_addr = inet_addr(ip);
 33     nw->len = sizeof(nw->addr);
 34     nw->type = type;
 35 
 36     if('s' == c_or_s)
 37     {
 38         if(bind(nw->fd,(SP)&nw->addr,nw->len))
 39         {
 40             perror("network bind");
 41             free(nw);
 42             return NULL;
 43         }
 44 
 45         if(SOCK_STREAM == type && listen(nw->fd,50))
 46         {
 47             perror("network listen");
 48             free(nw);
 49             return NULL;
 50         }
 51     }
 52     else if(SOCK_STREAM == type)
 53     {
 54         if(connect(nw->fd,(SP)&nw->addr,nw->len))
 55         {
 56             perror("network connect");
 57             free(nw);
 58             return NULL;
 59         }    
 60     }
 61 
 62     return nw;
 63 }
 64 
 65 // TCP的server专用
 66 NetWork* accept_network(NetWork* nw)
 67 {
 68     if(SOCK_STREAM != nw->type)
 69     {
 70         printf("network accept socket type error!\n");
 71         return NULL;
 72     }
 73 
 74     NetWork* clinw = malloc(sizeof(NetWork));
 75     if(NULL == clinw)
 76     {
 77         perror("network accept malloc");
 78         return NULL;
 79     }
 80     
 81     clinw->type = nw->type;
 82     clinw->len = sizeof(clinw->addr);
 83     clinw->fd = accept(nw->fd,(SP)&clinw->addr,&clinw->len);
 84     if(0 > clinw->fd)
 85     {
 86         perror("network accept");
 87         free(clinw);
 88         return NULL;
 89     }
 90 
 91     return clinw;
 92 }
 93 
 94 // 发送数据
 95 int nsend(NetWork* nw,void* buf,uint32_t len)
 96 {
 97     if(SOCK_STREAM == nw->type)
 98     {
 99         return send(nw->fd,buf,len,0);
100     }
101     else if(SOCK_DGRAM == nw->type)
102     {
103         return sendto(nw->fd,buf,len,0,(SP)&nw->addr,nw->len);
104     }
105     return -1;
106 }
107 
108 // 接收数据
109 int nrecv(NetWork* nw,void* buf,uint32_t len)
110 {
111     if(SOCK_STREAM == nw->type)
112     {
113         return recv(nw->fd,buf,len,0);
114     }
115     else if(SOCK_DGRAM == nw->type)
116     {
117         return recvfrom(nw->fd,buf,len,0,(SP)&nw->addr,&nw->len);
118     }
119     return -1;
120 }
121 
122 // 关闭网络连接
123 void close_network(NetWork* nw)
124 {
125     if(close(nw->fd))
126     {
127         perror("network close");
128     }
129     free(nw);
130 }

 

---------------------------------------------------------------------------------------------------------------------------------------------

Qt版(有界面)

内容比较多,可以直接看完整的项目

下面我们看看运行效果

完整的文件如下

在贴一个关键的代码好了

widget.cpp

  1 #include <iostream>
  2 #include <stdio.h>
  3 #include <dirent.h>
  4 #include <string.h>
  5 #include <sys/types.h>
  6 #include <sys/stat.h>
  7 #include <fcntl.h>
  8 #include <unistd.h>
  9 #include <sys/stat.h>
 10 #include <stdlib.h>
 11 #include "widget.h"
 12 #include "ui_widget.h"
 13 
 14 using namespace std;
 15 
 16 Widget::Widget(QWidget *parent) : QWidget(parent),ui(new Ui::Widget)
 17 {
 18     ui->setupUi(this);
 19 
 20     QPalette pal = this->palette(); // 设置背景图片
 21     pal.setBrush(QPalette::Background,QBrush(QPixmap(":/icon/bg.png")));
 22     setPalette(pal);
 23 
 24     download = false;
 25     upload = false;
 26 
 27     tcpSocket = new QTcpSocket;
 28     tcpSocket2 = new QTcpSocket;
 29     connect(tcpSocket,SIGNAL(connected()),this,SLOT(connect_success())); // 关联接收连接信号与槽函数
 30     connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(recv_msg()));
 31     connect(tcpSocket2,SIGNAL(connected()),this,SLOT(connect_success2()));
 32     connect(tcpSocket2,SIGNAL(readyRead()),this,SLOT(recv_msg2()));
 33 
 34 
 35     strcpy(clientdir,".");
 36     strcpy(serverdir,".");
 37     show_clientdir();   // 刚开始就显示客户端目录
 38 }
 39 
 40 Widget::~Widget()
 41 {
 42     delete ui;
 43 }
 44 
 45 // 显示客户端的所有文件
 46 void Widget::show_clientdir()
 47 {
 48     ui->clientdir->clear(); // 清空clientdir
 49     char cur_dir[1024];
 50     char* temp = getcwd(cur_dir, sizeof(cur_dir)-1); // 获取当前路径
 51     if(temp == NULL)
 52     {
 53         qDebug("获取当前路径失败");
 54     }
 55 
 56     qDebug("%s",cur_dir);
 57     ui->clientdir->setText(cur_dir);    // 设置clientdir的text
 58 
 59 
 60     int i = 0;
 61     DIR* dp = opendir(clientdir);
 62     for(struct dirent* file = readdir(dp); file!=NULL; file = readdir(dp))
 63     {
 64         client_filename[i++] = file->d_name;
 65 
 66         char img[256] = {};
 67 
 68         strcpy(img,":/icon/");
 69         if(file->d_type == DT_DIR)  // 判断是否是目录文件
 70         {
 71             strcat(img,"dir.png");
 72             //qDebug("dir");
 73         }
 74         else
 75         {
 76             strcat(img,"file.png");
 77         }
 78         QIcon icon(img);
 79         QListWidgetItem* item = new QListWidgetItem(icon,file->d_name);
 80         ui->listWidget_c->addItem(item);    // 添加字段
 81     }
 82 }
 83 
 84 // 显示服务端的所有文件
 85 void Widget::show_serverdir()
 86 {
 87     char list[20] = {};
 88     sprintf(list,"LIST -al\n");
 89     tcpSocket->write(list,strlen(list));
 90     tcpSocket->waitForBytesWritten();
 91 }
 92 
 93 // 点击connect按钮
 94 void Widget::on_connect_clicked()
 95 {
 96     QString _connect = ui->connect->text();
 97     if(_connect != "连接")
 98     {
 99         tcpSocket->close();
100         ui->connect->setText("连接");
101         ui->serverdir->clear();
102         ui->listWidget_s->clear();
103         return;
104     }
105 
106     QString _ip = ui->ip->text();   // 获取控件的text
107     QString _port = ui->port->text();
108 
109     const char* ip = _ip.toStdString().c_str();
110     short port = _port.toShort();
111 
112     tcpSocket->connectToHost(ip,port);  // 连接
113 
114     char username[60] = {};
115     sprintf(username,"USER %s\n",ui->username->text().toStdString().c_str());
116     tcpSocket->write(username,strlen(username));    // 发送命令
117     tcpSocket->waitForBytesWritten();
118 
119     //std::cout << "--" <<username <<"--" << endl;
120 
121     char password[60] = {};
122     sprintf(password,"PASS %s\n",ui->password->text().toStdString().c_str());
123     tcpSocket->write(password,strlen(password));
124     tcpSocket->waitForBytesWritten();
125 
126     char syst[20] = {};
127     sprintf(syst,"SYST\n");
128     tcpSocket->write(syst,strlen(syst));
129     tcpSocket->waitForBytesWritten();
130 
131     char opts[20] = {};
132     sprintf(opts,"OPTS UTF8 ON\n");
133     tcpSocket->write(opts,strlen(opts));
134     tcpSocket->waitForBytesWritten();
135 
136     char pwd[20] = {};
137     sprintf(pwd,"PWD\n");
138     tcpSocket->write(pwd,strlen(pwd));
139     tcpSocket->waitForBytesWritten();
140 
141     char pasv[20] = {};
142     sprintf(pasv,"PASV\n");
143     tcpSocket->write(pasv,strlen(pasv));
144     tcpSocket->waitForBytesWritten();
145 
146 
147     char list[20] = {};
148     sprintf(list,"LIST -al\n");
149     tcpSocket->write(list,strlen(list));
150     tcpSocket->waitForBytesWritten();
151 
152     ui->connect->setText("断开");
153 }
154 
155 // 初始端口
156 void Widget::recv_msg()
157 {
158     char buf1[1024] = {};
159     tcpSocket->read(buf1,sizeof(buf1));   // 接收数据
160     qDebug("%s",buf1);
161     bzero(buf,sizeof(buf));
162     strcpy(buf,buf1);
163     //qDebug("%s",buf);
164 
165     // PASV 227
166     if(strstr(buf1,"227") != NULL)
167     {
168         int ip1,ip2,ip3,ip4,port1,port2;    // 解析第二个端口号
169         sscanf(strchr(buf,'(')+1,"%d,%d,%d,%d,%d,%d",&ip1,&ip2,&ip3,&ip4,&port1,&port2);
170 
171         //std::cout << "port1:" << port1 << ",port2:"<< port2 << endl;
172 
173         int port3 = port1*256+port2;
174         QString _ip = ui->ip->text();
175         const char* ip = _ip.toStdString().c_str();
176 
177         tcpSocket2->connectToHost(ip,port3);    // 连接
178         //std::cout << "port:"<<port3<<",socket2 connect" << endl;
179     }
180 
181     // PWD 257
182     if(strstr(buf1,"257") != NULL)
183     {
184         char* str_pwd = (strpbrk(buf1,"\"")+1);  // 获取最后的字符串
185 
186         char* str1 = (strchr(str_pwd,'"'));  // 获取最后的字符串
187         str1[0] = '\0';
188 
189         str_pwd[strlen(str_pwd)] = '\0';  // 用\0替换\n
190         QByteArray byte(str_pwd);   // 解决中文乱码问题
191         QString dir(byte);
192         ui->serverdir->setText(dir);
193     }
194 
195 
196     // 150 down
197     if(strstr(buf1,"150 Opening BINARY mode data connection for") != NULL)
198     {
199         download = true;
200     }
201     // 150 up
202     if(strstr(buf1,"150 Ok to send data.") != NULL)
203     {
204         qDebug("收到150");
205         upload = true;
206 
207         int fd = open(file_name,O_RDONLY);
208 
209         qDebug("开始上传");
210         char buf3[10] = {};
211         while(read(fd,buf3,1) != 0) // 一次上传1字节
212         {
213             //qDebug("%s",buf3);
214             tcpSocket2->write(buf3,strlen(buf3));
215             bzero(buf3,sizeof(buf3));
216         }
217 
218         qDebug("上传完毕");
219         upload = false;
220         tcpSocket2->close();
221     }
222     // 226
223     if(strstr(buf1,"226 Transfer complete.") != NULL)
224     {
225         download = false;
226         upload = false;
227         ui->listWidget_c->clear();  // 清空listWidget_c
228         show_clientdir();
229     }
230 
231     bzero(buf1,sizeof(buf1));
232 
233 }
234 
235 // socket1连接成功
236 void Widget::connect_success()
237 {
238     qDebug("connected()");
239 }
240 
241 // tcpSocket2接收到消息
242 void Widget::recv_msg2()
243 {
244     ui->listWidget_s->clear();  // 清空listWidget_s
245     int i = 0;
246     while(1)
247     {
248         char buf2[1024]={};
249         tcpSocket2->readLine(buf2,sizeof(buf2));   // 接收数据
250         //qDebug("%s",buf2);
251 
252         if(strlen(buf2) <= 0)
253         {
254             break;
255         }
256         // 读取命令LIST -al返回的信息
257         if(buf2[1] == 'r' && (buf2[0] == '-'||buf2[0] == 'd'))
258         {
259             char img[256] = {};
260 
261             strcpy(img,":/icon/");
262             if(buf2[0] == 'd')  // 判断是否是目录文件
263             {
264                 strcat(img,"dir.png");
265                 //qDebug("dir");
266             }
267             else
268             {
269                 strcat(img,"file.png");
270             }
271             QIcon icon(img);
272 
273             char* str = (strrchr(buf2,' ')+1);  // 获取最后的字符串
274             str[strlen(str)-2] = '\0';  // 用\0替换\n
275             QByteArray byte(str);   // 解决中文乱码问题
276             QString filename(byte);
277             server_filename[i++] = filename;
278             QListWidgetItem* item = new QListWidgetItem(icon,filename);
279             ui->listWidget_s->addItem(item);    // 添加字段
280         }
281 
282         if(download == true)
283         {
284             // 读取下载的信息,写入文件
285             int fd = open(file_name,O_WRONLY|O_CREAT|O_APPEND,0666);
286             //qDebug("%s",buf2);
287             int ret = write(fd,buf2,strlen(buf2));
288             if(ret == 0)
289             {
290                 qDebug("写入完毕");
291             }
292         }
293 
294     }
295     tcpSocket2->close();
296 }
297 
298 // socket2连接成功
299 void Widget::connect_success2()
300 {
301     qDebug("connected()");
302 }
303 
304 // client的listWidget双击
305 void Widget::on_listWidget_c_doubleClicked(const QModelIndex &index)
306 {
307     qDebug("%d",index.row());   // 双击的index
308 
309     DIR* dp = opendir(".");
310     struct dirent* file = readdir(dp);
311     QString str;    // 存储文件名
312     if(index.row() == 0)
313     {
314         str = file->d_name;
315     }
316     for(int i=0; i<index.row(); i++)
317     {
318         file = readdir(dp);
319         if(i == index.row()-1)
320         {
321             str = file->d_name;
322         }
323     }
324 
325     QByteArray byte = str.toAscii();
326     char* filename =  byte.data();   // 文件名
327     qDebug("%s",filename);
328 
329     int ret = chdir(filename);    // 修改工作目录
330     if(ret == -1)
331     {
332         qDebug("chdir失败");
333     }
334 
335     ui->listWidget_c->clear();  // 清空
336     show_clientdir();
337 
338 }
339 
340 // server的listWidget双击
341 void Widget::on_listWidget_s_doubleClicked(const QModelIndex &index)
342 {
343     qDebug("%d",index.row());   // 双击的index
344 
345     QString str;    // 存储文件名
346     str = server_filename[index.row()];
347     QByteArray byte = str.toAscii();
348     char* filename = byte.data();   // 文件名
349     qDebug("%s",filename);
350 
351     char cwd[40] = {};
352     sprintf(cwd,"CWD %s\n",filename);
353     tcpSocket->write(cwd,strlen(cwd));
354     tcpSocket->waitForBytesWritten();
355 
356     char pwd[20] = {};
357     sprintf(pwd,"PWD\n");
358     tcpSocket->write(pwd,strlen(pwd));
359     tcpSocket->waitForBytesWritten();
360 
361 
362     char pasv[20] = {};
363     sprintf(pasv,"PASV\n");
364     tcpSocket->write(pasv,strlen(pasv));
365     tcpSocket->waitForBytesWritten();
366 
367     char list[20] = {};
368     sprintf(list,"LIST -al\n");
369     tcpSocket->write(list,strlen(list));
370     tcpSocket->waitForBytesWritten();
371 
372 }
373 
374 // 点击 << 下载按钮
375 void Widget::on_left_clicked()
376 {
377     download = true;
378 
379     QString str1 = server_filename[ui->listWidget_s->currentRow()]; // 获取选中的文件名
380     QByteArray byte = str1.toAscii();
381     char* temp = byte.data();
382     char filename[60] = {};
383     strcpy(file_name,temp); // 复制给全局变量
384     strcpy(filename,temp);
385     qDebug("%s",filename);
386 
387     char typea[40] = {};
388     sprintf(typea,"TYPE A\n");
389     tcpSocket->write(typea,strlen(typea));
390     tcpSocket->waitForBytesWritten();
391 
392     char size[60] = {};
393     sprintf(size,"SIZE %s\n",filename);
394     tcpSocket->write(size,strlen(size));
395     tcpSocket->waitForBytesWritten();
396 
397     char mdtm[60] = {};
398     sprintf(mdtm,"MDTM %s\n",filename);
399     tcpSocket->write(mdtm,strlen(mdtm));
400     tcpSocket->waitForBytesWritten();
401 
402     char pasv[20] = {};
403     sprintf(pasv,"PASV\n");
404     tcpSocket->write(pasv,strlen(pasv));
405     tcpSocket->waitForBytesWritten();
406 
407 
408     char retr[60] = {};
409     sprintf(retr,"RETR %s\n",filename);
410     tcpSocket->write(retr,strlen(retr));
411     tcpSocket->waitForBytesWritten();
412 
413     char pwd[20] = {};
414     sprintf(pwd,"PWD\n");
415     tcpSocket->write(pwd,strlen(pwd));
416     tcpSocket->waitForBytesWritten();
417 
418     char pasv1[20] = {};
419     sprintf(pasv1,"PASV\n");
420     tcpSocket->write(pasv1,strlen(pasv1));
421     tcpSocket->waitForBytesWritten();
422 
423     char list[20] = {};
424     sprintf(list,"LIST -al\n");
425     tcpSocket->write(list,strlen(list));
426     tcpSocket->waitForBytesWritten();
427 
428 }
429 
430 // 点击 >> 上传按钮
431 void Widget::on_right_clicked()
432 {
433     QString str1 = client_filename[ui->listWidget_c->currentRow()]; // 获取选中的文件名
434     QByteArray byte = str1.toAscii();
435     char* temp = byte.data();
436     char filename[60] = {};
437     strcpy(file_name,temp); // 复制给全局变量
438     strcpy(filename,temp);
439     qDebug("%s",filename);
440 
441     int fd = open(filename,O_RDONLY,0666);
442     if(fd < 0)
443     {
444         qDebug("不是文件,上传失败");
445         upload = false;
446         return;
447     }
448 
449     char typea[60] = {};
450     sprintf(typea,"TYPE A\n");
451     tcpSocket->write(typea,strlen(typea));
452     tcpSocket->waitForBytesWritten();
453 
454     char size[60] = {};
455     sprintf(size,"SIZE %s\n",filename);
456     tcpSocket->write(size,strlen(size));
457     tcpSocket->waitForBytesWritten();
458 
459     char pasv[20] = {};
460     sprintf(pasv,"PASV\n");
461     tcpSocket->write(pasv,strlen(pasv));
462     tcpSocket->waitForBytesWritten();
463 
464     char stor[60] = {};
465     sprintf(stor,"STOR %s\n",filename);
466     tcpSocket->write(stor,strlen(stor));
467     tcpSocket->waitForBytesWritten();
468 
469     while(upload == true)
470     {
471         usleep(1000);
472         qDebug("while...");
473     }
474 
475     char mdtm[60] = {};
476     sprintf(mdtm,"MDTM %s\n",filename);
477     tcpSocket->write(mdtm,strlen(mdtm));
478     tcpSocket->waitForBytesWritten();
479 
480     char pwd[20] = {};
481     sprintf(pwd,"PWD\n");
482     tcpSocket->write(pwd,strlen(pwd));
483     tcpSocket->waitForBytesWritten();
484 
485     char pasv1[20] = {};
486     sprintf(pasv1,"PASV\n");
487     tcpSocket->write(pasv1,strlen(pasv1));
488     tcpSocket->waitForBytesWritten();
489 
490     char list[20] = {};
491     sprintf(list,"LIST -al\n");
492     tcpSocket->write(list,strlen(list));
493     tcpSocket->waitForBytesWritten();
494 
495 }
496 
497 
498 // 客户端目录回车
499 void Widget::on_clientdir_returnPressed()
500 {
501     QString str = ui->clientdir->text();    // 存储文件名
502     QByteArray byte = str.toAscii();
503     char* filename =  byte.data();   // 文件名
504     qDebug("%s",filename);
505 
506     int ret = chdir(filename);    // 修改工作目录
507     if(ret == -1)
508     {
509         qDebug("chdir失败");
510     }
511 
512     ui->listWidget_c->clear();  // 清空
513     show_clientdir();
514 }
515 
516 // 服务端目录回车
517 void Widget::on_serverdir_returnPressed()
518 {
519     QString str = ui->serverdir->text();    // 存储文件名
520     QByteArray byte = str.toAscii();
521     char* filename = byte.data();   // 文件名
522     qDebug("%s",filename);
523 
524     char cwd[40] = {};
525     sprintf(cwd,"CWD %s\n",filename);
526     tcpSocket->write(cwd,strlen(cwd));
527     tcpSocket->waitForBytesWritten();
528 
529     char pwd[20] = {};
530     sprintf(pwd,"PWD\n");
531     tcpSocket->write(pwd,strlen(pwd));
532     tcpSocket->waitForBytesWritten();
533 
534 
535     char pasv[20] = {};
536     sprintf(pasv,"PASV\n");
537     tcpSocket->write(pasv,strlen(pasv));
538     tcpSocket->waitForBytesWritten();
539 
540     char list[20] = {};
541     sprintf(list,"LIST -al\n");
542     tcpSocket->write(list,strlen(list));
543     tcpSocket->waitForBytesWritten();
544 }

 

转载于:https://www.cnblogs.com/ikaros-521/p/11507240.html

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐