实现文件传输并不难,只需用fopen、fread、fwrite、fclose这几个函数对文件操作即可。文本文件就不说了,我们就已下图为例。
我们先来看看这个图片文件里装的是什么,我们以notpad++打开这个图片,结果如下,是一堆乱码。
我们在已二进制方式打开,方式如下:
首先打开vs的一个项目
选择一张图片
这张图片添加到源文件后,右键这张图片,选择打开方式
选择二进制编辑器
结果如下
图片文件是以二进制方式存储的,因为二进制更加节省空间,所以我们在用fopen函数时注意都要以二进制的形式读或写。
我们以客户端作发送方,服务器作接收方,先在客户端的源码目录下放一张图片123.jpg,启动服务器后在启动客户端,便在服务器的目录下产生一张与123.jpg一样的图片456.jpg。
服务器
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
int main()
{struct sockaddr_in sock;memset(&sock,0,sizeof(sock));sock.sin_family=AF_INET;sock.sin_port=htons(5188);sock.sin_addr.s_addr=htonl(INADDR_ANY);int sockid=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);const int on=1;setsockopt(sockid,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));if(bind(sockid,(struct sockaddr *)&sock,sizeof(sock))<0){printf("bind\n");return 0;}if(listen(sockid,SOMAXCONN)<0){printf("listen\n");return 0;}struct sockaddr_in other_sock;socklen_t other_socklen=sizeof(other_sock);int client_sockid=accept(sockid,(struct sockaddr *)&other_sock,&other_socklen);printf("ip=%s,port=%d\n",inet_ntoa(other_sock.sin_addr),ntohs(other_sock.sin_port));FILE *fp=fopen("456.jpg","wb");char receive[4096]={0};int r_size=0;while(1){memset(receive,0,sizeof(receive));if((r_size=read(client_sockid,receive,sizeof(receive)))==0)//读取文件内容,如果客户端已全部发送,则read返回0,因为客户端发送完后就退出{printf("已成功接收\n");break;}fwrite(receive,1,r_size,fp);//读了多少数据就往文件里写多少数据}close(client_sockid);close(sockid);fclose(fp);return 0;
}
客户端
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main()
{struct sockaddr_in sock;memset(&sock,0,sizeof(sock));sock.sin_family=AF_INET;sock.sin_port=htons(5188);sock.sin_addr.s_addr=inet_addr("***");//服务器ipint sockid=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);socklen_t socklen=sizeof(sock);connect(sockid,(struct sockaddr *)&sock,socklen);FILE *fp=fopen("123.jpg","ab");char send[4096]={0};int r_size;while(!feof(fp))//判断文件指针是否到达文件末尾{r_size=fread(send,1,sizeof(send),fp);//读取文件数据write(sockid,send,r_size);,//读多少数据就发多数据给服务器memset(send,0,strlen(send));}printf("发送成功\n");close(sockid);fclose(fp);return 0;
}
用这个办法不仅可以传输文件,还可以传输视频文件,只需把文件名称更改一下即可