linux socket c/s上传文件

这是上传文件的一个示例,可以参照自行修改成下载或者其它功能。

在上传时,需要先将文件名传到服务器端,这是采用一个结构体,包含文件名及文件名长度(可以用于校验),防止文件名乱码。

client

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "wrap.h"
#define MAXLINE 1492
#define SERV_PORT 5555
#define FILE_NAME_LEN 64

struct fileInfo{
    char fileName[FILE_NAME_LEN];
    int len;
};

int main(int argc, char *argv[])
{
    if(argc<3){
        perror("Usage:./a.out ip filename");
        exit(-1);
    }
    struct sockaddr_in servaddr;
    char buf[MAXLINE];
    int sockfd;
    //char servip[]="123.206.59.137";
    sockfd = Socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);
    Connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    struct fileInfo file_name;
    memset(&file_name,0,sizeof(file_name));
    strncpy(file_name.fileName,argv[2],strlen(argv[2]));
    file_name.len=strlen(argv[2]);
    Write(sockfd,&file_name,sizeof(file_name));
    FILE *fp=fopen(argv[2],"r");
    if(fp==NULL){
        perror("open file failed");
        Close(sockfd);
        exit(-1);
    }
    printf("open file %s successed\n",argv[2]);
    int len=0;
    while ((len=fread(buf,sizeof(char),MAXLINE,fp))>0) {
        Write(sockfd, buf, len);
    }
    fclose(fp);
    Close(sockfd);
    return 0;
}

server

#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include "wrap.h"
#define MAXLINE 1492
#define SERV_PORT 5555
#define FILE_NAME_LEN 64
struct fileInfo{
    char fileName[FILE_NAME_LEN];
    int len;
};

int main(int argc, char *argv[]){
    struct sockaddr_in serveraddr;
    int listenfd;
    char str[INET_ADDRSTRLEN];

    listenfd=Socket(AF_INET,SOCK_STREAM,0);
    bzero(&serveraddr,sizeof(serveraddr));
    serveraddr.sin_family=AF_INET;
    serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);
    serveraddr.sin_port=htons(SERV_PORT);

    Bind(listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
    Listen(listenfd,20);

    while(1){
        struct sockaddr_in clientaddr;
        socklen_t addrLen=sizeof(clientaddr);
        int confd=Accept(listenfd,(struct sockaddr *)&clientaddr,&addrLen);
        printf("receive file from %s at port %d\n",
            inet_ntop(AF_INET,&clientaddr.sin_addr,str,sizeof(str)),
            ntohs(clientaddr.sin_port)
        );
        int len=0;
        struct fileInfo file_name;
        len=Read(confd,&file_name,sizeof(file_name));
        if(len==0){
            Close(confd);
        }else {
            printf("file name len=%d\n",file_name.len);
            printf("file name is %s\n",file_name.fileName);
        }
        char buf[MAXLINE];
        FILE *fp=fopen(file_name.fileName,"w");
        if(!fp){
            perror("open file failed");
            Close(confd);
            Close(listenfd);
        }
        while((len=Read(confd,buf,MAXLINE))>0){
            fwrite(buf,sizeof(char),len,fp);
        }
        if(len==0){
            fclose(fp);
            printf("receive file done\n");
            Close(confd);
        }
    }
    Close(listenfd);
    return 0;
}

wrap.c

#include "wrap.h" 

/*********************************************************************
 * * Name      : perr_exit
 * * Description    : exit the function
 * * Input    : the error string
 * * Output    :
 * * Return    :
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
void perr_exit(const char *s)
{
    perror(s);
    exit(1);
} 

/*********************************************************************
 * * Name      : Accept
 * * Description    : accept a connection on a socket
 * * Input    : fd---a socket that has been created
 * * sa---a pointer to a sockaddr structure
 * * salenptr---actual size of the peer address
 * * Output    :
 * * Return    : the descriptor for the accepted socket
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
    int n; 

again:
    if((n = accept(fd, sa, salenptr)) < 0) {
        if((ECONNABORTED == errno) || (EINTR == errno))
            goto again;
        else
            perr_exit("accept error");
    } 

    return n;
} 

/*********************************************************************
 * * Name      : Bind
 * * Description    : bind a name to a socket
 * * Input    : fd---a socket that has been created
 * * sa---a pointer to a sockaddr structure
 * * salen---the size of the address structure
 * * Output    :
 * * Return    :
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
void Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
    if(bind(fd, sa, salen) < 0)
        perr_exit("bind error");
} 

/*********************************************************************
 * * Name      : Connect
 * * Description    : initiate a connection on a socket
 * * Input    : fd---a socket that has been created
 * * sa---a pointer to a sockaddr structure
 * * salen---the size of the address structure
 * * Output    :
 * * Return    :
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
void Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
    if(connect(fd, sa, salen) < 0)
        perr_exit("connect error");
} 

/*********************************************************************
 * * Name      : Listen
 * * Description    : listen for connections on a socket
 * * Input    : fd---a socket that has been created
 * * backlog---the maximum length to the queue of
 * * pending connections
 * * Output    :
 * * Return    :
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
void Listen(int fd, int backlog)
{
    if(listen(fd, backlog) < 0)
        perr_exit("listen error");
} 

/*********************************************************************
 * * Name      : Socket
 * * Description    : create an endpoint for communication
 * * Input    : family---a communication domain
 * * type---the communication semantics
 * * protocol---a particular protocol for the socket
 * * Output    :
 * * Return    : return a descriptor of the socket
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
int Socket(int family, int type, int protocol)
{
    int n; 

    if((n = socket(family, type, protocol)) < 0)
        perr_exit("socket error");
    return n;
} 

/*********************************************************************
 * * Name      : Read
 * * Description    : read from a file descriptor
 * * Input    : fd---a socket that has been created
 * * ptr---the buffer which storage the bytes
 * * nbytes---the number of bytes read
 * * Output    :
 * * Return    : return the number of bytes read
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
ssize_t Read(int fd, void *ptr, size_t nbytes)
{
    ssize_t n; 

again:
    if((n = read(fd, ptr, nbytes)) == -1) {
        if(EINTR == errno)
            goto again;
        else
            return -1;
    }    

    return n;
} 

/*********************************************************************
 * * Name      : Write
 * * Description    : write to a file descriptor
 * * Input    : fd---a socket that has been created
 * * ptr---buffer of the bytes
 * * nbytes---the number of bytes written
 * * Output    :
 * * Return    : return the number of bytes written
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
ssize_t Write(int fd, const void *ptr, size_t nbytes)
{
    ssize_t n; 

again:
    if((n = write(fd, ptr, nbytes)) == -1) {
        if(EINTR == errno)
            goto again;
        else
            return -1;
    } 

    return n;
} 

/*********************************************************************
 * * Name      : Close
 * * Description    : close a file descriptor
 * * Input    : fd---a socket that has been created
 * * Output    :
 * * Return    :
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
void Close(int fd)
{
    if(close(fd) == -1)
        perr_exit("close error");
} 

/*********************************************************************
 * * Name      : Readn
 * * Description    : read from a file descriptor,
 * * make sure read the enough bytes
 * * Input    : fd---a socket that has been created
 * * ptr---the buffer which storage the bytes
 * * nbytes---the number of bytes read
 * * Output    :
 * * Return    : return the number of bytes read
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
ssize_t Readn(int fd, void *vptr, size_t nbytes)
{
    size_t nleft;
    size_t nread;
    char *ptr; 

    ptr = vptr;
    nleft = nbytes; 

    while(nleft > 0) {
        if((nread = read(fd, ptr, nleft)) < 0) {
            if(EINTR == errno)
                nread = 0;
            else
                return -1;
        } else if(nread == 0)
            break; 

        nleft -= nread;
        ptr += nread;
    } 

    return (nbytes-nleft);
} 

/*********************************************************************
 * * Name      : Writen
 * * Description    : write to a file descriptor,
 * * make sure write the enough bytes
 * * Input    : fd---a socket that has been created
 * * ptr---the buffer which storage the bytes
 * * nbytes---the number of bytes read
 * * Output    :
 * * Return    : return the number of bytes read
 * * Others    : by jzk 2009.12.02
 * **********************************************************************/
ssize_t Writen(int fd, const void *vptr, size_t nbytes)
{
    size_t nleft;
    size_t nwritten;
    const char *ptr; 

    ptr = vptr;
    nleft = nbytes; 

    while(nleft > 0) {
        if((nwritten = write(fd, ptr, nleft)) <= 0) {
            if(nwritten < 0 && EINTR == errno)
                nwritten = 0;
            else
                return -1;
        } 

        nleft -= nwritten;
        ptr += nwritten;
    } 

    return nbytes;
}

static ssize_t my_read(int fd,char *ptr)
{
    static int read_cnt;
    static char *read_ptr;
    static char read_buf[100];

    if(read_cnt<=0){
again:
        if((read_cnt=read(fd,read_buf,sizeof(read_buf))<0)){
            if(errno==EINTR)
                goto again;
                return -1;
        }else if(read_cnt==0)
            return 0;
        read_ptr=read_buf;
    }
    read_cnt--;
    *ptr=*read_ptr++;
    return 1;
}
size_t Read_line(int fd,void *vptr,size_t maxlen)
{
    ssize_t n,rc;
    char c,*ptr;

    ptr=vptr;
    for(n=1;n<maxlen;n++){
        if((rc=my_read(fd,&c))==1){
            *ptr++=c;
            if(c==‘\n‘)
                break;
        }else if(rc==0){
            *ptr=0;
            return n-1;
        }else
             return -1;
    }
    *ptr=0;
    return n;
}

wrap.h

#ifndef WRAP_H
#define WRAP_H 

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h> 

void perr_exit(const char *s); 

int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);
void Bind(int fd, const struct sockaddr *sa, socklen_t salen);
void Connect(int fd, const struct sockaddr *sa, socklen_t salen);
void Listen(int fd, int backlog); 

int Socket(int family, int type, int protocol);
void Close(int fd); 

ssize_t Read(int fd, void *ptr, size_t nbytes);
ssize_t Write(int fd, const void *ptr, size_t nbytes); 

ssize_t Readn(int fd, void *vptr, size_t n);
ssize_t Writen(int fd, const void *vptr, size_t n); 

ssize_t Readline(int fd, void *vptr, size_t maxlen); 

#endif 

Makefile

######################################
#
#######################################
#source file
#源文件,自动找所有.c和.cpp文件,并将目标定义为同名.o文件
SOURCE  := $(wildcard *.c) $(wildcard *.cpp)
OBJS    := $(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(SOURCE)))

#target you can change test to what you want
#目标文件名,输入任意你想要的执行文件名
TARGET  := client server
APP1    := client
APP2    := server

MAINS    :=$(APP1).o $(APP2).o
#compile and lib parameter
#编译参数
CC      := gcc
LIBS    := -lpthread -lrt
LDFLAGS :=
DEFINES :=
INCLUDE := -I.
CFLAGS  := -g -Wall -O3 $(DEFINES) $(INCLUDE)
CXXFLAGS:= $(CFLAGS) -DHAVE_CONFIG_H

#i think you should do anything here
#下面的基本上不需要做任何改动了
.PHONY : everything objs clean veryclean rebuild

everything : $(TARGET)

all : $(TARGET)

objs : $(OBJS)

rebuild: veryclean everything

clean :
    rm -fr *.so
    rm -fr *.o

veryclean : clean
    rm -fr $(TARGET)

$(APP1) :$(APP1).o $(filter-out $(MAINS), $(OBJS))
    $(CC)  $(CXXFLAGS) -o [email protected] $^  $(LDFLAGS) $(LIBS)
$(APP2) :$(APP2).o $(filter-out $(MAINS), $(OBJS))
    $(CC)  $(CXXFLAGS) -o [email protected] $^  $(LDFLAGS) $(LIBS)
时间: 2024-10-13 20:22:24

linux socket c/s上传文件的相关文章

Linux中ftp不能上传文件/目录的解决办法

在linux中不能上传文件或文件夹最多的问题就是权限问题,但有时也不一定是权限问题了,像我就是空间不够用了,下面我来总结一些ftp不能上传文件/目录的解决办法 在排除用户组和权限等问题后,最可能引起ftp下文件无法上传并经常被忽略的因素就是硬盘空间已满,而导致硬盘空间满的问题多数是日志文件所占用的,例如mysql的日志会在不知不觉中变得十分庞大,直至占满剩余的硬盘空间. 解决办法: 1.定期手动清理或使用脚本清理mysql日志或其他相关日志文件. 2.关闭mysql日志(不推荐) 上面是空间有问

Linux服务器下载与上传文件

一.图形化工具 FileZilla.SecureCRT,连接Linux服务器后直接操作 二.命令 使用终端模拟软件连接服务器后,首先安装lrzsz工具包 yum install lrzsz rz ,上传文件 sz filename  ,下载文件(只能下载文件,文件夹考虑先打包  tar -czvf xxx.tar.gz xxx/  将xxx文件夹打包压缩为xxx.tar.gz文件) 原文地址:https://www.cnblogs.com/lingblog/p/11963489.html

“通过jumpserver远程登录linux服务器,rz上传文件速度过慢”问题的解决

问题: windows通过jumpserver远程登录到linux服务器,使用rz上传jar包,速度太慢(10k以内). 解决方案: 思路:通过ssh直接登录远程服务器 1.secureCRT-> tools->create public key 2.新建登录远程服务器的session 3.设置session的property,将authentication中的password选项去除,并将publickey选项的properties设置成identity 4.通过jumpserver登录远程

linux 系统filezilla无法上传文件 553 Could not create

做网站过程中遇见了很多问题,解决了但是解决方法过一段时间就会遗忘,整理出来以便以后查看. 响应: 553 Could not create file.错误: 严重文件传输错误 解决方案: 一.必须将站点的文件上传到 /htdocs 目录(windows不用) 二.将属性中的权限修改为777 附上filezilla初次正确使用方法: 启动FileZilla软件,新建站点:单击 文件 > 站点管理器  > 新站点 . 新站点,名字可任意填写,如填写为:新站点. 主机,填入主机的IP地址,如:121

linux下实现ftp上传文件

上传: #!/bin/sh set -x set -e local_rootPath=/hadoop/datadir/windeploy/temp host="192.168.12.2" # 需要上传的ftp地址 port="21" # 端口 user="ftpuser" # ftp登陆的用户名 passwd="123456" # ftp 登陆用户口令 customer="aaa" ftp -n<&l

vmware里面的linux怎么和windows相互传文件

我们常常遇到这样的问题.高版本号的vmware遇到低版本号的linux.使用起来就比較抠脚,比方低版本号的linux安装在高版本号的vmware里. 1.不能全屏显示虚拟机 2.每次切换出来.总要按一下Ctrl+Alt键 3.特别可恨的是不能直接互传文件 针对以上情况.本篇博客仅仅是针对第三个问题展开的,怎么将vmware里的linux和外面的window互传文件,方法非常多,有 1.建立共享文件夹 2.通过建立ftp,也就是把windows当做ftp的server 3.建立linux的tftp

windows上传文件到 linux的hdfs

一.windows上传文件到 linux的hdfs 1.先在 centos 上开启 hdfs, 用 jps 可以看到下面信息, 说明完成开启 2.在win上配置 hadoop (https://www.cnblogs.com/Jomini/p/11432484.html) 后, 要在 hadoop 的 bin 文件上放以下两个文件(网上找下载), 3.创建 maven 工程, 运行读写程序 pom 文件 <dependency> <groupId>org.apache.loggin

Linux服务器通过aws命令行上传文件至S3

目的Linux服务器通过AWS命令行上传文件至S3 配置打开你的AWS控制台: 连接你的Linux服务器,按照以下步骤操作: # 安装pip yum -y install python-pip   # 安装awscli pip install awscli   # 初始化配置 aws configure # 做这一步时系统会要求你输入"访问密钥ID"."私有访问密钥"."默认区域名称"."默认输出格式",前两个在创建IAM用户

CI支持各种文件上传-文件类型(Linux + window)

$mimes = array( 'hqx' => 'application/mac-binhex40', 'cpt' => 'application/mac-compactpro', 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv'