C/C++、Qt4实现FTP客户端(有无界面版)
作者:互联网
操作系统:Ubuntu 12.04 LTS
开发工具:GNU4.6.3,C/C++标准库,Qt4,Qt Creator Documentation 2.4.1
相关知识点参考:
网络通信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 }
标签:FTP,Qt4,tcpSocket,strlen,C++,char,sizeof,buf,nw 来源: https://www.cnblogs.com/ikaros-521/p/11507240.html