首页 > 编程知识 正文

网络编程和socket编程的关系,socket网络编程有关代码

时间:2023-05-04 09:28:19 阅读:19383 作者:4905

前言文件传输是聊天室的最后一个功能,这个博客仍然站在聊天室的项目背景上。

既然两个客户端可以通过套接字进行通信,那么传输文件的难点在于如何接收和离线发送文件。

文件发送主要有以下两种模式。

客户端-客户端(实时文件发送)客户端-服务器-客户端(脱机文件发送)首先,确定用于发送文件的函数。 sendfile ) )。

搜索sendfile函数时,大多数博客似乎都介绍了sendfile零拷贝的优点,但找不到我最需要的。 那个怎么用?

SYNOPSIS

#include sys/sendfile.h

size_tsendfile(intout_FD,int in_fd,off_t *offset,size_t count );

说得再多也比不上例行公事的直接。 以下是第一版代码,服务器和客户端之间的连接步骤很繁琐,代码可以放在文末,必要时直接往下拉复制。 这里只显示传输文件部分的代码。

客户端-服务器

客户端(发送方) :

# define bufsize 1024 char * file _ name; char buf[BUFSIZE]; char file_path[BUFSIZE]; printf ('请输入完整的路径名: '; Sanf('%s ',file_path ); //确定路径名是否正确的if(stat(file_path,buffer )=-1 ) printf(----不正确的路径名---n ' ); 继续; //获取文件名file_name=basename(file_path ); //将文件名发送到接收方strcpy(buf,file_name )的write(CFD,buf,BUFSIZE ); //这里采用定长协议发送文件intFP=open(file_path,O_CREAT|O_RDONLY,S_IRUSR|S_IWUSR )。 //文件开始发送printf (---- -文件:%s---n (,buf ); sendfile(CFD,fp,0,buffer.st_size ); printf('---文件%s传输成功---n ',buf; //关闭文件描述符和套接字关闭(FP )关闭(CFD; 服务器端(接收端)

# define bufsize 1024 char file _ name [ bufsize ]; char file_path[BUFSIZE]; char buf[BUFSIZE]; //接收文件名read(CFD,file_name,BUFSIZE ); 如果希望在特定目录下接收//文件,可以添加这样的步骤//默认值保存到当前文件夹//当前文件夹下的file_buf/目录中包含sprintf(file_path,文件路径) 文件//文件file * FP=创建fopen (file _ path,' wb ' )的if(FP==null ) Perror(can'topenfile ); 退出(1; //将数据写入文件while ((n=读取) CFD,buf,BUFSIZE ) ) fwrite ) buf,sizeof(char ),n,fp; //关闭文件描述符和套接字fclose(FP )的close(CFD; 至此,我们第一个发送文件的任务完成了。

但是在接收方read返回值0时停止循环while。注意阻止并等待数据,而不是在套接字中读取数据后返回0。

从发送方套接字关闭到发送FIN数据包为止,read将返回0并退出循环。

这里的内容详见以下。

3359 ZF L9.github.io/c-socket.html

但是,这样显然不足以达到我们的需要。 作为聊天室,如果插座断开,应该如何通信? 因此,read ) )应该设计一个判断点来判断是否传输了文件,而不是阻止并等待FIN包。

在发送端把文件的长度提前发送至接收端

很简单。 将文件的长度和文件名保存到结构中

struct len_name{unsigned int len; char name[NAME_MAX]; (; 但是,write (),read ) )只能发送和接收字符串类型的分组,所以这里有几个类型转换

客户端(发送方)

struct len_name ln; ln.len=buffer.buffer.st_size; strcpy(ln.name,file_name ); //类型转换//按字节复制结构的内存在buf中char buf[BUFSIZE]; memcpy(buf,ln,sizeof ) ln ); 发送//write (CFD、buf、BUFSIZE ); 服务器端(接收端)

struct len_name ln; char buf[BUFSIZE]; 收到//read(CFD、buf、BUFSIZE ); //类型转换memcpy(ln,buf,sizeof ) ln ); 然后,只需稍微修改接收方的接收文件部分,即可解决上述问题。

服务器端(接收端)

char buf[BUFSIZE]; int len; 未指定int sum=0; file * FP=fopen (时间,' wb ' ); while((n=read ) CFD,buf,BUFSIZE ) )0) fwrite ) buf,sizeof(char ),n,fp ); sum =n; 在收到if(sum=ln.len )//足够长的时间点,文件的读取就完成了{break; }完整的代码请参阅此处:

3359 github.com/hiyoyolumi/chat room/tree/master/file _ test

通过将发送方写入服务器,将接收方写入客户端,可以实现服务器------客户端

对于客户端的实时传输文件模式,在掌握上述文件传输技术后也能容易实现,但本文对此不写代码。

基本思路与客户端-服务器基本一致。 服务器获取两个客户端的套接字,一个发送方接收,服务器充当一个中继即可。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。