TCP文件传输

下面是一个简单的TCP文件传输的例子,实现环境:Linux C

Server.c

// 向客户端发送文件
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define MAXBUFF 1024
// 通过sock来发送指定的文件
int sendFile(char *srcFile, int sock)
{
int inFile;
if((inFile = open(srcFile, O_RDONLY)) == -1) //只读方式打开test.txt ,iffile文件指针
{
printf("找不到文件[%s]或打不开, 停止运行\n", srcFile);
return -1;								// 发送文件失败
}
int nread;
char buf[MAXBUFF] = {0};
while((nread = read(inFile, buf, MAXBUFF)) > 0)
{
if(write(sock, buf, nread) == -1)		// 将缓冲区的内容写到sock
printf("写sock出了错\n");
}
close(inFile);
return 0;									// 发送文件成功
}
int main()
{
int sock,length,clilen;
struct sockaddr_in server, client;
/******************************建立Socket连接*********************************/
sock = socket(AF_INET,SOCK_STREAM,0); //申请socket资源
if (sock < 0)
{
perror("socket");
return 1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;	// 必然的,这里指的是Internet协议*/
server.sin_port = 0;					// 这里,是让系统自动分配一个端口号,在1024到5000之间65535个端口 ,端口设为0,系统自动分配  
if (bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0) // 将IP地址和端口号绑到sock上
{
perror("bind");
return 1;
}
length = sizeof(server);
if (getsockname(sock, (struct sockaddr *)&server, &length) < 0) /*获得指定socket的本地地址,成功返回0,错误返回-1*/
{
perror("getsockname");
return 1;
}
printf("Socket port #%d\n", ntohs(server.sin_port)); /* 打印出系统分的端口号,给client用*/
listen(sock, 5);									/*5个连接请求排队等待,一般5个 Pause Here 等待client连接*/
/****************现在是等待客户来连接,如果来客户了,那就建好了socket,就可以当文件使用**********/
clilen = sizeof(client);   
int msgsock = accept(sock,(struct sockaddr *)&client,(int *) &clilen);	/*创建一个新的与sock相同的socket并返回其值*/
if (msgsock == -1)
perror("accept");
else
{
char srcFile[] = "test.txt";
if(sendFile(srcFile, msgsock) == 0)
printf("发送文件[%s]成功\n", srcFile);
else
printf("发送文件[%s]失败\n", srcFile);
} 
close(msgsock);									// 关闭临时套接字
close(sock);
return 0;
}


Client.c

// 功能:接收服务器发送过来的数据,保存到本地文件
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define MAXBUFF 1024
#define PERM 0644			// 创建文件的默认属性
// 通过sock接收数据保存到文件destFile
int recvFile(char *destFile, int sock)
{
int outFile, nread;
char buf[MAXBUFF] = {0};
if((outFile = open(destFile, O_WRONLY|O_CREAT|O_TRUNC, PERM)) == -1) //创建文件
return 1;
while((nread = read(sock, buf, MAXBUFF)) > 0) /*从sock读取传来的文件内容到缓冲区*/
{ 
if(write(outFile, buf, nread) == -1)		/*将缓冲区的内容写到文件里*/
{
printf("写文件时出错, 中止接收文件\n");
close(outFile);
return 1;
}
}
close(outFile);
return 0;
}
int main(int argc, char *argv[])
{
int sock;
struct sockaddr_in server;
struct hostent *hp;
if(argc < 3)
{
printf("Usage: %s <hostname> <server port>\n", argv[0]);
return 1;
}
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
perror("socket");
return 1;
}
server.sin_family = AF_INET;
hp = gethostbyname(argv[1]); /*根据主机名查地址,返回指针指向hostent结构*/
if (hp == 0)
{
fprintf(stderr, "%s: unknown host\n", argv[1]);
return 1;
}
memcpy((char *)&server.sin_addr,(char *)hp->h_addr, hp->h_length);	// 拷贝Internet地址
server.sin_port = htons(atoi(argv[2]));								// argv[2]是服务器端口号
if (connect(sock,(struct sockaddr *)&server,sizeof(server)) < 0)	// 根据server地址连接sock,建立一条真实的连接
{
perror("connect");
close(sock);
return 1;
}
char destFile[] = "test_out.txt";
if(recvFile(destFile, sock) == 0)
{
printf("接收文件[%s]成功\n\n", destFile);
}
else
{
printf("创建输出文件[%s]出错, 请检查\n", destFile);
}
close(sock);
return 0;
}


如果要检查文件传输过程有没有出错,可以通过命令:wc或计算MD5值来作比较。

我的检测结果:

[zcm@t #64]$cat test.txt |wc
89     183    2901
[zcm@t #65]$cat test_out.txt |wc
89     183    2901
[zcm@t #66]$md5sum test.txt test_out.txt 
fffb6bcab6154aad9f7dfe4f5d945bc3  test.txt
fffb6bcab6154aad9f7dfe4f5d945bc3  test_out.txt


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/407287.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

javascript学习系列(14):数组中的indexOf方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说…

Git之撤销修改

自然&#xff0c;你是不会犯错的。不过现在是凌晨两点&#xff0c;你正在赶一份工作报告&#xff0c;你在readme.txt中添加了一行 在你准备提交前&#xff0c;一杯咖啡起了作用&#xff0c;你猛然发现了“stupid boss”可能会让你丢掉这个月的奖金&#xff01; 既然错误发现得…

glibc与MSVC CRT(转载)

glibc与MSVC CRT 运行库是平台相关的&#xff0c;因为它与操作系统结合得非常紧密。C语言的运行库从某种程度上来讲是C语言的程序和不同操作系统平台之间的抽象层&#xff0c;它将不同的操作系统API抽象成相同的库函数。比如我们可以在不同的操作系统平台下使用fread来读取文件…

asp.net下载的三种方式

Codeprotected void Button1_Click(object sender, EventArgs e) { /* 微软为Response对象提供了一个新的方法TransmitFile来解决使用Response.BinaryWrite 下载超过400mb的文件时导致Aspnet_wp.exe进程回收而无法成功下载的问题。 …

输出一个文件的最后n行数据,如果文件总行数不足n行,则显示全部数据

C程序&#xff0c;功能如题&#xff0c;代码如下&#xff1a; /*功能&#xff1a;输出一个文件的最后n行数据&#xff0c;如果文件总行数不足n行&#xff0c;则显示全部数据基本思路&#xff1a;产生一个长度为n的二维数组&#xff0c;将它作为一个循环队列来看待*/#include &…

javascript学习系列(13):数组中的concat方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说c…

如何阻止表单的默认提交事件

表单一点击提交按钮(submit)必然跳转页面&#xff0c;如果表单的action为空也会跳转到自己的页面&#xff0c;即效果为刷新当前页。 如下&#xff0c;可以看到一点击提交按钮&#xff0c;浏览器的刷新按钮闪了一下&#xff1a; 如果想要阻止表单的默认提交事件&#xff0c;有以…

c#winform使用WebBrowser 大全[超长文转载]

1、主要用途&#xff1a;使用户可以在窗体中导航网页。 2、注意&#xff1a;WebBrowser 控件会占用大量资源。使用完该控件后一定要调用 Dispose 方法&#xff0c;以便确保及时释放所有资源。必须在附加事件的同一线程上调用 Dispose 方法&#xff0c;该线程应始终是消息或用户…

nessuss中文使用手册

Nessus使用手册&#xff0c;主要介绍了在各系统下的安装方式&#xff0c;以及怎么使用。转载于:https://blog.51cto.com/infosec/95054

exit(),_exit()的区别

Linux的源码 #define __NR_exit 1 #define __NR__exit __NR_exit /* 摘自文件include/asm-i386/unistd.h*/ "__NR_"是在Linux的源码中为每个系统调用加上的前缀&#xff0c;请注意第一个exit前有2条下划线&#xff0c;第二个exit前只有1条下划线…

javascript学习系列(15):数组中的lastIndexOf方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说…

iOS新版微信底部返回横条问题

之前没有怎么接触过微信开发&#xff0c;只是对H5比较熟。最近维护一个微信公众号的项目&#xff0c;遇到了iOS端返回键的坑。 描述一下&#xff1a; 从公众号打开页面后&#xff0c;底部有个返回的小横条&#xff0c;恰好也挡住了页面。这不行啊&#xff0c;得解决。 页面的高…

【ExtJS】FormPanel 布局(一)

准备工作&#xff0c;布置一个最简单的Form&#xff0c;共5个组件&#xff0c;都为textfield。 1 Ext.onReady(function(){2 Ext.create(Ext.form.Panel, {3 width: 500,4 title: Layout,5      renderTo : form,6 items: [{7 xt…

squid代理架构

代理服务器是使用非常普遍的一种将局域网主机联入互联网的一种方式&#xff0c;使用代理上网可以节约紧缺的IP地址资源&#xff0c;而且可以阻断外部主机对内部主机的访问&#xff0c;使内部网主机免受外部网主机的***。但是&#xff0c;如果想让互联网上的主机访问内部网的主机…

JS之四舍五入Fixed

用法&#xff1a;toFixed() 方法可把 Number 四舍五入为指定小数位数的数字 语法&#xff1a;NumberObject.toFixed(num) 参数&#xff1a;必需。规定小数的位数&#xff0c;是 0 ~ 20 之间的值&#xff0c;包括 0 和 20&#xff0c;有些实现可以支持更大的数值范围。如果省略…

输出上下对称的星型

输出星型&#xff0c;如&#xff1a; ******************************* C code: // 用法如&#xff1a;a.exe 7#include<stdio.h>int main(int argc, char *argv[]){if(argc < 2){printf("Usage: %s <n>\n", argv[0]);}else{int n atoi(argv[1]);i…

javascript学习系列(16):数组中的every方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说…

JS之Number的toString方法

作用&#xff1a;toString() 方法可把一个 Number 对象转换为一个字符串&#xff0c;并返回结果 语法&#xff1a;NumberObject.toString(radix) 参数&#xff1a;可选。规定表示数字的基数&#xff0c;使 2 ~ 36 之间的整数。若省略该参数&#xff0c;则使用基数 10。但是要…

signal函数说明

c traps and pitfalls 对signal函数解释得非常详细。 <signal.h> 中 void ( *signal( int sig, void (* handler)( int ))) ( int ); int (*p)(); 这是一个函数指针, p所指向的函数是一个不带任何参数, 并且返回值为int的一个函数. int (*fun())(); 这个式子与上面式子…

javascript学习系列(17):数组中的find方法

最好的种树是十年前,其次是现在。歌谣 每天一个前端小知识 提醒你改好好学习了 知乎博主 csdn博主 b站博主 放弃很容易但是坚持一定很酷 我是歌谣 喜欢就一键三连咯 你得点赞是对歌谣最大的鼓励 1前言 在我们的日常开发中 不免会有很多需要处理数据的方法 本节主要说一说…