学习一下用socket进行文件传输,从服务器下载文件。
运行结果(客户端):
成功从服务器下载MV“起风了 ” 。
源代码:
服务器端:
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll
const int BUFSIZE = 1024;
int main()
{
//先检查文件是否存在
//文件名
char *filename = "D:\\send.mp4";
//以二进制方式打开文件
FILE *fp = fopen(filename, "rb");
if(fp == NULL)
{
printf("Cannot open file, press any key to exit!\n");
system("pause");
exit(0);
}
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
//创建套接字
SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0);
//绑定套接字
sockaddr_in servAddr;
//每个字节都用0填充
memset(&servAddr, 0, sizeof(servAddr));
//使用IPv4地址
servAddr.sin_family = AF_INET;
//具体的IP地址
servAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
//端口
servAddr.sin_port = htons(1234);
bind(servSock, (sockaddr *)&servAddr, sizeof(servAddr));
//进入监听状态
listen(servSock, 20);
//接收客户端请求
sockaddr clntAddr;
int nSize = sizeof(sockaddr);
SOCKET clntSock = accept(servSock, &clntAddr, &nSize);
//缓冲区
char buffer[BUFSIZE] = {0};
int nCount = 0;
//循环发送数据,直到文件结尾
while( (nCount = fread(buffer, 1, BUFSIZE, fp)) > 0)
send(clntSock, buffer, nCount, 0);
//文件读取完毕,断开输出流,向客户端发送FIN包
shutdown(clntSock, SD_SEND);
//阻塞,等待客户端接收完毕。
recv(clntSock, buffer, BUFSIZE, 0);
fclose(fp);
//关闭套接字
closesocket(clntSock);
closesocket(servSock);
//终止 DLL 的使用
WSACleanup();
return 0;
}
客户端:
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib") //加载 ws2_32.dll
const int BUFSIZE = 1024;
int main()
{
//先输入文件名,看文件是否能创建成功
//文件名
char filename[100] = {0};
printf("Input filename to save: ");
gets(filename);
//以二进制方式打开(创建)文件
FILE *fp = fopen(filename, "wb");
if(fp == NULL)
{
printf("Cannot open file, press any key to exit!\n");
system("pause");
exit(0);
}
//初始化DLL
WSADATA wsaData;
WSAStartup(MAKEWORD(2,2), &wsaData);
//创建套接字
SOCKET clntSock = socket(AF_INET, SOCK_STREAM, 0);
//向服务器发起请求
sockaddr_in clntAddr;
//每个字节都用0填充
memset(&clntAddr, 0, sizeof(clntAddr));
clntAddr.sin_family = AF_INET;
clntAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
clntAddr.sin_port = htons(1234);
connect(clntSock, (sockaddr *)&clntAddr, sizeof(clntAddr));
//循环接收数据,直到文件传输完毕
//文件缓冲区
char buffer[BUFSIZE] = {0};
int nCount = 0;
while( (nCount = recv(clntSock, buffer, BUFSIZE, 0)) > 0)
fwrite(buffer, 1, nCount, fp);
printf("File transfer success!\n");
//文件接收完毕后直接关闭套接字,无需调用shutdown().
fclose(fp);
//关闭套接字
closesocket(clntSock);
//终止使用 DLL
WSACleanup();
system("pause");
return 0;
}