Linux C Socket编程:文件上传
一个服务端等待, 客户端上传文件到服务端,通过输入要上传的文件名,目前只做到仅对当前执行文件的目录下的文件,应该在服务端收到文件路径之后进行处理的。
服务端代码:
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero #define SERVER_PORT 6666
#define LISTEN_QUEUE 20
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512 int main(int argc, char **argv)
{
//设置一个socket地址结构server_addr,代表服务器internet地址, 端口
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr)); //把一段内存区的内容全部设置为0
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(SERVER_PORT); //创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
int server_socket = socket(PF_INET, SOCK_STREAM, );
if (server_socket < )
{
printf("Create Socket Failed!");
exit();
} //把socket和socket地址结构联系起来
if (bind(server_socket, (struct sockaddr*) &server_addr,
sizeof(server_addr)))
{
printf("Server Bind Port: %d Failed!\n", SERVER_PORT);
exit();
} //server_socket用于监听
if (listen(server_socket, LISTEN_QUEUE))
{
printf("Server Listen Failed!");
exit();
} while ()
{
//定义客户端的socket地址结构client_addr
char buffer[BUFFER_SIZE];
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr); int client_socket = accept(server_socket,
(struct sockaddr*) &client_addr, &length);
if (client_socket < )
{
printf("Server Accept Failed!\n");
break;
}
bzero(buffer, BUFFER_SIZE);
// 获取客户端要传输的文件名
length = recv(client_socket, buffer, BUFFER_SIZE, );
if (length < )
{
printf("Server Recieve Data Failed!\n");
break;
}
char file_name[FILE_NAME_MAX_SIZE + ];
bzero(file_name, FILE_NAME_MAX_SIZE + );
strncpy(
file_name,
buffer,
strlen(buffer) > FILE_NAME_MAX_SIZE? FILE_NAME_MAX_SIZE : strlen(buffer)); // 新建文件
FILE * fp = fopen(file_name, "w");
if (NULL == fp)
{
printf("File: %s CAN NOT WRITE!\n", file_name);
}
else
{
bzero(buffer, BUFFER_SIZE);
int file_block_length = ;
while ((file_block_length = recv(client_socket, buffer, BUFFER_SIZE, )) > )
{
if (file_block_length < )
{
printf("Recieve Data From Client Failed!\n");
break;
}
int write_length = fwrite(buffer, sizeof(char), file_block_length, fp);
if (write_length < file_block_length)
{
printf("File: %s Write Failed\n", file_name);
break;
}
bzero(buffer, BUFFER_SIZE);
}
fclose(fp);
printf("File: %s Transfer Finished\n\n", file_name);
}
//关闭与客户端的连接
close(client_socket);
}
//关闭监听用的socket
close(server_socket);
return ;
}
客户端代码:
#include <netinet/in.h> // for sockaddr_in
#include <sys/types.h> // for socket
#include <sys/socket.h> // for socket
#include <stdio.h> // for printf
#include <stdlib.h> // for exit
#include <string.h> // for bzero
/*
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
*/ #define SERVER_PORT 6666
#define BUFFER_SIZE 1024
#define FILE_NAME_MAX_SIZE 512 int main(int argc, char **argv)
{
if (argc != )
{
printf("Please input the IP address of the server \n", argv[]);
exit();
} //设置一个socket地址结构client_addr,代表客户机internet地址, 端口
struct sockaddr_in client_addr;
bzero(&client_addr, sizeof(client_addr)); //把一段内存区的内容全部设置为0
client_addr.sin_family = AF_INET; //internet协议族
client_addr.sin_addr.s_addr = htons(INADDR_ANY); //INADDR_ANY表示自动获取本机地址
client_addr.sin_port = htons(); //0表示让系统自动分配一个空闲端口
//创建用于internet的流协议(TCP)socket,用client_socket代表客户机socket
int client_socket = socket(AF_INET, SOCK_STREAM, );
if (client_socket < )
{
printf("Create Socket Failed!\n");
exit();
}
//把客户机的socket和客户机的socket地址结构联系起来
if (bind(client_socket, (struct sockaddr*) &client_addr,
sizeof(client_addr)))
{
printf("Client Bind Port Failed!\n");
exit();
} //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
if (inet_aton(argv[], &server_addr.sin_addr) == ) //服务器的IP地址来自程序的参数
{
printf("Server IP Address Error! \n");
exit();
} server_addr.sin_port = htons(SERVER_PORT);
socklen_t server_addr_length = sizeof(server_addr);
// 向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接
if (connect(client_socket, (struct sockaddr*) &server_addr,
server_addr_length) < )
{
printf("Can Not Connect To %s!\n", argv[]);
exit();
} // 连接上服务器, 选择要上传的文件
char file_name[FILE_NAME_MAX_SIZE + ];bzero
(file_name, FILE_NAME_MAX_SIZE + );
printf("Please Input File Name Upload To Server: ");
scanf("%s", file_name); char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
strncpy(buffer, file_name,
strlen(file_name) > BUFFER_SIZE? BUFFER_SIZE : strlen(file_name)); FILE * fp = fopen(file_name, "r");
if (NULL == fp)
{
printf("File: %s NOT FOUND! \n", file_name);
exit();
} // 发送文件名
int nameLength = send(client_socket, buffer, BUFFER_SIZE, );
if (nameLength < )
{
printf("File name Error! \n");
exit();
} bzero(buffer, BUFFER_SIZE);
int file_block_length = ; while ((file_block_length = fread(buffer, sizeof(char), BUFFER_SIZE, fp))
> )
{
if (send(client_socket, buffer, file_block_length, ) < )
{
printf("Send File:\t%s Failed\n", file_name);
break;
}
bzero(buffer, BUFFER_SIZE);
}
printf("File:\t%s Transfer Finished\n", file_name);
fclose(fp);
close(client_socket);
return ;
}
代码很多是复制的,慢慢看一行行看懂之后把原来别人的客户端下载改成客户端上传,其实都差不多,服务端与客户端connect之后基本上就是文件读写的事了。
来自:http://www.cnblogs.com/lycheng/archive/2011/11/08/2240518.html
Linux C Socket编程:文件上传的更多相关文章
- Python Socket实现文件上传(TCP协议)
在TCP协议下通过socket模块实现文件上传 #!/usr/bin/env python # -*- coding: utf-8 -*- # desc: tcp_server_file_upload ...
- socket实现文件上传(客户端向服务器端上传照片示例)
本示例在对socket有了基本了解之后,可以实现基本的文件上传.首先先介绍一下目录结构,server_data文件夹是用来存放客户端上传的文件,client_data是模拟客户端文件夹(目的是为了测试 ...
- Linux小工具:文件上传ftp服务器
工作期间,每次将文件上传至ftp服务器时,均需要手工输入ip.用户名.密码等,因此,考虑编写脚本完成文件的上传任务.具体的脚本sync.sh如下: #!/bin/bash source ~/.bash ...
- PHP核心编程--文件上传(包含多文件上传)
一.单文件上传 图片上传界面: <!DOCTYPE html> <html lang="en"> <head> <meta charset ...
- linux 客户端与linux服务器端连接与文件上传下载
linux客户端连接linux服务器 用ssh 可以用 man ssh 查看用法 基本格式: ssh 用户名@主机名 如: ssh root@1.1.1.1 linux客户端上传文件到 linux 服 ...
- linux下将本地文件上传到github中?
今天编写一份Python基础代码,经过Linux上传到github上,遇到点问题,已经解决 1.首先sudo su 进入root 用户 2.ls 检查出当前文件下有什么文件 3. cd 进入你将要上传 ...
- python2.7入门---CGI编程&文件上传&文件下载
这次我们来看下文件下载和上传的操作.首先是上传,HTML设置上传文件的表单需要设置 enctype 属性为 multipart/form-data,代码如下所示: <!DOCTYPE h ...
- ASP.NET Web API编程——文件上传
首先分别介绍正确的做法和错误的做法,然后分析他们的不同和错误之处,以便读者在实现此功能时可避开误区 1正确的做法 public class AvaterController : BaseApiCont ...
- C# Socket大文件上传
public sealed class SocketData { private SocketData() { } public static SendFileMode SendFile(Socket ...
- 从原理角度解析Android (Java) http 文件上传
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23781773 文件上传是我们项目中经常使用的功能,一般我们的服务器可能都是web ...
随机推荐
- vi编辑器简介
vi编辑器是Linux和Unix上最基本的文本编辑器,工作在字符模式下.由于不需要图形界面,vi是效率很高的文本编辑器.尽管在Linux上也有很多图形界面的编辑器可用,但vi在系统和服务器管理中的功能 ...
- KVM虚拟机的管理
1. 查看KVM虚拟机配置文件及运行状态 (1) KVM虚拟机默认配置文件位置: /etc/libvirt/qemu/ autostart目录是配置kvm虚拟机开机自启动目录 (2) virsh命令 ...
- 数据库索引碎片——数据库sql
文章:检测和整理索引碎片 文章:[笔记整理]SQL Server 索引碎片 和 重建索引 文章介绍了检查表的索引碎片百分比 文章:[小问题笔记(八)] 常用SQL(读字段名,改字段名,打印影响行数,添 ...
- vue---子调父 $emit (把子组件的数据传给父组件)
ps:App.vue 父组件 Hello.vue 子组件 ps:App.vue 父组件 Hello.vue 子组件 <!--App.vue :--> <template> & ...
- C++读取中文或英文文件空格分割
// show file content - sbumpc() example #include <iostream> // std::cout, std::streambuf #incl ...
- Git----拉取远程分支,git pull,git rebase,git pull --rebase的区别
git pull 相当于自动的 fetch 和 merge 操作,会试图自动将远程库合并入本地库,在有冲突时再要求手动合并. git rebase 可以确保生产分支commit是一个线性结构,方便ro ...
- HDU-1465-不容易系列之一(容斥)
链接: https://vjudge.net/problem/HDU-1465 题意: 大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了! 做好"一件"事情尚且不易 ...
- 树状数组例题-数星星,简单题easy,校门外的树2,清点人数
[例1]数星星 天空中有一些星星,这些星星都在不同的位置,每个星星都有个坐标,如果一个星星的左下方(包括正左和正下)有k颗星星,就说这颗星星是k级的. 比如,上图中,星星5是3级的(1,2,4在其左下 ...
- Jedis常用方法API
一.键操作 二.字符串操作 三.整数和浮点数操作 四.列表(List)操作 五.集合(Set)操作 六.哈希(Hash)操作 七.有序集合(Zsort)操作 八.排序操作
- MongoDB 分片管理(二)查看网络连接
1.1 查看连接统计 connPoolStats,查看mongos与mongod之间的连接信息,并可得知服务器 上打开的所有连接 1.2 限制连接数量