发现以前可能了解的少,就愚蠢至极,其实linux的ftp非常简单
直接sudo apt-get install vsftpd就可以了然后去etc下面去该配置文件就可以了,可能debian的redhat风格的linux的配置文件的路径可能不太一样。
只需要将配置文件里面的#write_enable=YES前面的#号去掉应该就能够上传文件了,还没试过没有去掉#号能不能上传,我都去掉了的
以前愚蠢是因为什么以为只需要再地址栏ftp://ip/地址输入就能到达ftp的路径了。但是这个确实设置了匿名可以这么搞,但是如果没有设置匿名他不会触发账户和密码的弹框的,不像windows本身的ftp配置,输入如果对方有账户和密码会触发弹框。
如果不想装xftp等三方的ftp工具的话可以直接控制台输入ftp
open ip后输入用户名和密码
然后lcd切换本地文件夹
put本地文件里面的内容
下面是前两年其实也可以实现把windows上的压缩包传到linux服务器上面去,这样也不需要安装ftp服务。今年拿来试了一下还是可以的,虽然我觉得以前愚蠢至极,但是这些功能是真的实现了的,给自己点个赞已经很棒了。
因为某些原因我需要在linux上操作一些东西,但是不知道为什么VMware tools可以进行小文件从windows向ubuntu复制,复制稍大文件电脑直接卡死,不知道什么原因。索性想用ftp ,但是ubuntu下配置的vsftp死活用不了,最后想到了用socke传输文件。
linux端,只能把windows上的zip传向linux
linux上的c代码,再linux上创建一个这个文件比如叫recive_zip.c
gcc recive_zip -o recive_zip
产生的文件后./recive_zip 6666
就开始监听了
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <errno.h>
#include <netinet/ip.h>
#include <sys/stat.h>
#include <unistd.h>
int removeZero(char* filename){
FILE* fp = fopen(filename,"rb");
fseek(fp,-2048,SEEK_END);
char buf[2048];
char end[8];
memset(end,0,8);
end[0]=80;
end[1]=75;
end[2]=5;
end[3]=6;
memset(buf,0,2048);
fread(buf,1,2048,fp);
int i;
char* tmp = buf;
for(i=0;i<2048;i++){
if(*tmp==*end){
if(0 == memcmp(tmp,end,8)){printf("has find\nthis i is%d\n",i);break;}
}
tmp++;
}
fclose(fp);
struct stat statbuf;
if(stat(filename,&statbuf)<0){
perror("stat get file szie failed\n");
return -1;
}
if(truncate(filename,statbuf.st_size-(2048-i-22))<0){
perror("truncate failed\n");
return -1;
};
return 0;
}
int main(int argc,char** argv)
{
if(argc < 2){
printf("Usage:<%s><port>",argv[0]);
exit(-1);
}
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(0 > sockfd)
{
perror("socket");
exit(-1);
}
struct sockaddr_in seraddr={
.sin_family=AF_INET,
.sin_port=htons(atoi(argv[1])),
.sin_addr.s_addr=htonl(INADDR_ANY)
};
struct sockaddr_in cli_addr;
memset(&cli_addr,0,sizeof(cli_addr));
if(0 > bind(sockfd,(struct sockaddr*)&seraddr,sizeof(seraddr)))
{
perror("bind");
exit(-1);
}
if(0 > listen(sockfd,10))
{
perror("listen");
exit(-1);
}
printf("listen.........\n");
int len = sizeof(struct sockaddr_in);
int trans_sock = accept(sockfd,(struct sockaddr*)&cli_addr,&len);
char msg[2048];
if(trans_sock == -1){
perror("accept");
}
printf("connect come form :%s\n",inet_ntoa(cli_addr.sin_addr));
memset(msg,0,2048);
int count = recv(trans_sock,msg,2048,0);
printf("%d,%s\n",count,msg);
char filename[128];
strcpy(filename,msg);
FILE* fp = fopen(msg,"wb+");
while(1){
memset(msg,0,2048);
count = recv(trans_sock,msg,2048,0);
if(count == 0){
if(errno != EINTR){
printf("connection disconnected\n");
removeZero(filename);
close(trans_sock);
close(sockfd);
fclose(fp);
return 0;
}
}
printf("recv %d bytes\n",count);
fwrite(msg,count,1,fp);
}
close(trans_sock);
close(sockfd);
fclose(fp);
return 0;
}
windows端在devc++ panda 6.7.5上运行成功
为什么devc++经久不衰,你看哈vs现在的版本下载都是几个G,devc++都没多大,轻量级都占用不了啥资源
一下可以创建个文件send_zip.c
编译后直接在cmd 里面输入send_zip.exe 对端linux的ip 6666 文件路径名
devc++可以去百度下载
我把send_zip.exe和recive_zip上传到我的资源里面去
以前还愚蠢只知道ifconfig能够看ip
后来才知道ip addr也能看,有些不会预装ifconfig 但是ip工具是会预装的
需要在工具-编译选项-在链接时加入以下参数-static-libgcc -lws2_32
#include <winsock2.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {
if (argc < 4) {
printf("Usage<%s> <ip> <port> <filename>", argv[0]);
exit(-1);
}
WSADATA wsd;
if ((WSAStartup(MAKEWORD(2, 2), &wsd)) != 0) {
printf( "wsastartup()failed: \n");
exit(1);
}
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
printf("socket error\n");
exit(-1);
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);
addr.sin_port = htons(atoi(argv[2]));
if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) {
printf("connect error\n");
return -1;
}
char buf[2048];
FILE* fp = fopen(argv[3], "rb");
if (fp == NULL) {
printf("open %s failed,if this file exist?\n", argv[3]);
exit(-1);
}
int count = 0;
strcpy(buf,argv[3]);
count = send(sock,buf, 2048,0);
printf("witre %d bytes\n", count);
while(!feof(fp)){
memset(buf,0,2048);
count = fread(buf,1,2048,fp);
printf("read %d bytes\n",count);
send(sock,buf,2048,0);
}
closesocket(sock);
printf("%s\n",argv[3]);
WSACleanup();
return 0;
}
send和recv并不是发多少 收到多少 在调试的时候windows上读到的2048个字节到linux上打印却有小于2048的。这个可能是因为二进制发送和tcp分片的原因吧,也不想再用wireshark抓包验证了。应该是linux上用2048的buf一次没取完,然后第二次就recv就小于2048了
用了16进制编辑器linux上的ghex观察所有zip的编码都是 50 4B 05 06 00 00 00 00 + 14个字符 一共22个字符;
这里还有两个linux下缩小文件大小的方法,stat 和truncate方法;fseek fwrite都没有办法改变文件大小。