源码:https://github.com/Lee-johnH/my_study.git
先上截图:
首先我有个Faded.mp3的文件在目录/mnt下,现在我要把它通过服务器传给客户端,传到客户端所在的文件目录下,并命名为new_Faded.mp3.
先执行服务器,并输入端口号,然后让客户端通过端口号向服务器发送连接请求,连接成功,服务器询问应将哪个文件传给客户端,输入原文件名,再输入新文件名,文件传输过去,传输完毕则提示传输成功。客户端用ls查看文件是否传输过来,目录下多了个new_Fade.mp3,并确认可以使用该文件,传输成功!
实现思路:
服务器端:socket-->bind-->listen-->accept
客户端: socket-->connect
服务器建立套接字为网络通讯做基本准备,bind将本地的端口同socket返回的文件描述符捆绑在一起,listen函数将bind的文件描述符变为监听套接字,然后调用accept函数进入阻塞状态,直到客户端程序发出连接请求,便建立全双工通信。
建立连接之后,先在服务器输入要传输的文件名,并保存在file_name[]数组当中,然后再输入新的文件名存入file_name_save[]中,将新的文件名通过send()函数发送给客户端,客户端通过recv()函数接收,并以此名打开文件进行写操作。
在传送文件时我选择使用一个零拷贝函数sendfile(),好处是在传输文件时无需进入用户态,而是在内核态和磁盘直接就将文件传输过去,一来减少内核分配buffer的时间及空间,二来电脑无需从内核态切换到用户态,再从用户态切换到内核态,从而大大减少时间。保证在传输大文件时速度也很快,云盘的秒传技术用到了这个函数。
最后,文件传输完毕服务器提示传输成功,客户端提示接收成功,并检验传输过来的文件是否可用。