Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';在C中使用多线程服务器时,无法完成文件传输_C_Multithreading_File_Pthreads - Fatal编程技术网

Can';在C中使用多线程服务器时,无法完成文件传输

Can';在C中使用多线程服务器时,无法完成文件传输,c,multithreading,file,pthreads,C,Multithreading,File,Pthreads,我有一个多线程客户端,可以将一批文件传输到客户端自己创建的新目录。我的客户端以前使用单线程服务器 对于任务,我应该将单线程服务器转换为多线程服务器,为每个客户端请求创建一个新线程。我还应该对整个操作计时并将其输出到客户机(当服务器是单线程的时候,我就开始工作了)。多线程客户端(可与单线程服务器一起使用)和多线程服务器(无法正常工作)的代码如下: 客户c #include <sys/uio.h> #include <sys/stat.h> #include <unis

我有一个多线程客户端,可以将一批文件传输到客户端自己创建的新目录。我的客户端以前使用单线程服务器

对于任务,我应该将单线程服务器转换为多线程服务器,为每个客户端请求创建一个新线程。我还应该对整个操作计时并将其输出到客户机(当服务器是单线程的时候,我就开始工作了)。多线程客户端(可与单线程服务器一起使用)和多线程服务器(无法正常工作)的代码如下:

客户c

#include <sys/uio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <pthread.h>
#include <string.h>
#include <strings.h>
#include "Timer.h"

#define N_THREADS 10

char * files[] = {
    "/usr/share/dict/words",
    "/usr/include/sqlite3.h",
    "/usr/include/tclDecls.h",
    "/usr/include/bfd.h",
    "/usr/include/libmng.h",
    "/usr/include/elf.h",
    "/usr/include/gmpxx.h",
    "/usr/include/tkDecls.h",
    "/usr/include/H5overflow.h",
    "/usr/include/tcl.h",
    "/usr/include/gmp-x86_64.h",
    "/usr/include/curses.h",
    "/usr/include/lcms.h",
    "/usr/include/netapi.h",
    "/usr/include/gcrypt.h",
    "/usr/include/zlib.h",
    "/usr/include/ldap.h",
    "/usr/include/geos_c.h",
    "/usr/include/kdb.h",
    "/usr/include/tk.h",
    "/usr/include/yaml.h"
};

#define files_length() (sizeof files / sizeof files[0])

void error(char *msg)
{
    perror(msg);
    exit(-1);
}

struct sockaddr_in make_server_addr(char *host, short port)
{
    struct sockaddr_in addr;
    bzero(&addr, sizeof addr);
    struct hostent *hp = gethostbyname(host);
    if ( hp == 0 )
        error(host);
    addr.sin_family = AF_INET;
    bcopy(hp->h_addr_list[0], &addr.sin_addr, hp->h_length);
    addr.sin_port = htons(port);
    return addr;
}

int connect_socket(char *host, short port)
{
    int status;
    int tries = 3;
    struct sockaddr_in addr = make_server_addr(host, port);
    int s = socket(AF_INET, SOCK_STREAM, 0);
    if ( s == -1 )
        error("socket()");
    status = connect(s, (struct sockaddr*)&addr, sizeof addr);
    if ( status < 0 )
        error("connect refused");
    return s;
}

void request_file_from_server(int server_socket, char *file)
{
    int len = strlen(file);
    int n = write(server_socket, file, len);
    if ( n != len )
        error("short write");
}

void read_file_from_server(int server_socket, char *file)
{
    char buf[BUFSIZ];
    int n;
    mode_t mode = 0666;
    int ofd = open(file, O_WRONLY | O_CREAT, mode);
    if ( ofd == -1 )
        perror("open()");
    while ( (n = read(server_socket, buf, BUFSIZ)) > 0 )
        write(ofd, buf, n);
    close(ofd);
}


struct Thread_data
{
    int id;
    pthread_t thread_id;
    char * host;
    short port;
    char path[BUFSIZ];
};

void make_file_name(char *local_name, char *dir, char *original_path)
{
    char *p = rindex(original_path, '/');
    if ( !p )
        error("rindex()");
    sprintf(local_name, "%s/%s", dir, p+1);
}

int remote_copy(struct Thread_data * data, char * file)
{
    int server_socket = connect_socket(data->host, data->port);
    request_file_from_server(server_socket, file);
    char local_name[BUFSIZ];
    make_file_name(local_name, data->path, file);
    read_file_from_server(server_socket, local_name);
    close(server_socket);
}

void make_empty_dir_for_copies(struct Thread_data * data)
{
    mode_t mode = 0777;
    sprintf(data->path, "./Thread_%d", (data->id + 1));
    mkdir(data->path, mode);
}

#define N_FILES_TO_COPY files_length() // copy them all

void *thread_work(void *arg)
{
    struct Thread_data * data = (struct Thread_data *)arg;
    make_empty_dir_for_copies(data);
    for ( int i=0; i < N_FILES_TO_COPY; ++i )
        remote_copy(data, files[i]);
    pthread_exit(0);
}

void start_threads(char *host, short port, struct Thread_data thread_args[])
{
    for ( int i = 0; i < N_THREADS; ++i )
    {
        struct Thread_data * t = &thread_args[i];
        t->id = i;
        t->host = host;
        t->port = port;
        pthread_create(&t->thread_id, NULL, thread_work, t);
    }
}

void join_threads(struct Thread_data thread_args[], double *eTime)
{
    for ( int i=0; i < N_THREADS; i++ )
        pthread_join(thread_args[i].thread_id, NULL);
    Timer_elapsedUserTime(eTime);
    printf("Elapsed time for transferring all files: %lf\n", *eTime);
    pthread_exit(0);
}

int main(int argc, char *argv[])
{
    if ( argc != 3 )
    {
        fprintf(stderr, "Usage: %s host port\n", argv[0]);
        exit(-1);
    }

    struct Thread_data thread_args[N_THREADS];
    char *host = argv[1];
    short port = atoi(argv[2]);
    double eTime;
    Timer_start();
    start_threads(host,port,thread_args);
    join_threads(thread_args, &eTime);

}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“Timer.h”
#定义N_线程10
字符*文件[]={
“/usr/share/dict/words”,
“/usr/include/sqlite3.h”,
“/usr/include/tclDecls.h”,
“/usr/include/bfd.h”,
“/usr/include/libmng.h”,
“/usr/include/elf.h”,
“/usr/include/gmpxx.h”,
“/usr/include/tkDecls.h”,
“/usr/include/H5overflow.h”,
“/usr/include/tcl.h”,
“/usr/include/gmp-x86_64.h”,
“/usr/include/curses.h”,
“/usr/include/lcms.h”,
“/usr/include/netapi.h”,
“/usr/include/gcrypt.h”,
“/usr/include/zlib.h”,
“/usr/include/ldap.h”,
“/usr/include/geos_c.h”,
“/usr/include/kdb.h”,
“/usr/include/tk.h”,
“/usr/include/yaml.h”
};
#定义文件\u length()(sizeof files/sizeof files[0])
无效错误(字符*消息)
{
佩罗尔(味精);
出口(-1);
}
make_服务器_addr中的结构sockaddr_(char*主机,短端口)
{
地址中的结构sockaddr\u;
bzero(地址和地址,地址大小);
结构hostent*hp=gethostbyname(主机);
如果(hp==0)
错误(主机);
addr.sin_family=AF_INET;
b复制(hp->h_地址列表[0],&addr.sin_地址,hp->h_长度);
地址SINU port=htons(端口);
返回地址;
}
int connect_插座(字符*主机,短端口)
{
智力状态;
int=3;
addr中的struct sockaddr\u=make\u server\u addr(主机、端口);
int s=套接字(AF_INET,SOCK_STREAM,0);
如果(s==-1)
错误(“socket()”);
状态=连接(s,(struct sockaddr*)和addr,sizeof addr);
如果(状态<0)
错误(“连接被拒绝”);
返回s;
}
来自服务器的无效请求文件(int server套接字,char*文件)
{
int len=strlen(文件);
int n=写入(服务器\u套接字、文件、len);
如果(n!=len)
错误(“短写”);
}
无效从服务器读取文件(int server套接字,char*文件)
{
char buf[BUFSIZ];
int n;
模式=0666;
int ofd=打开(文件,O|U WRONLY | O|U CREAT,模式);
如果(ofd==-1)
perror(“open()”);
而((n=read(server_socket,buf,BUFSIZ))>0)
写入(ofd,buf,n);
关闭(ofd);
}
结构线程数据
{
int-id;
pthread_t thread_id;
字符*主机;
短端口;
字符路径[BUFSIZ];
};
无效生成文件名(字符*本地名称,字符*目录,字符*原始路径)
{
char*p=rindex(原始路径“/”);
如果(!p)
错误(“rindex()”);
sprintf(本地名称,“%s/%s”,dir,p+1);
}
int远程拷贝(结构线程数据*数据,字符*文件)
{
int server_socket=connect_socket(数据->主机,数据->端口);
从服务器请求文件(服务器套接字,文件);
char local_name[BUFSIZ];
生成文件名(本地文件名,数据->路径,文件);
从\u服务器读取\u文件\u(服务器\u套接字,本地\u名称);
关闭(服务器_套接字);
}
void make_empty_dir_用于复制(结构线程数据*数据)
{
模式=0777;
sprintf(数据->路径,“./Thread_uu%d”,(数据->id+1));
mkdir(数据->路径,模式);
}
#定义N\u文件\u到\u复制文件\u长度()//复制所有文件
void*线程\u工作(void*arg)
{
结构线程数据*数据=(结构线程数据*)参数;
为拷贝(数据)制作空的目录;
对于(int i=0;iid=i;
t->host=host;
t->port=port;
pthread\u create(&t->thread\u id,NULL,thread\u work,t);
}
}
无效连接线程(结构线程数据线程参数[],双*时间)
{
对于(int i=0;i
服务器.c

#include <sys/types.h>
#include <signal.h>
#include <sys/uio.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <pthread.h>
#include <string.h>
#include "Timer.h"

#define BACKLOG 200
// more than this in the queue, and client connect will fail
#define NUM_THREADS 200


void error(char *msg)
{
    fprintf(stderr, "%s\n", msg);
    exit(-1);
}


struct sockaddr_in make_server_addr(short port)
{
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof addr);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY;
    return addr;
}

int create_server_socket(short port)
{
    int s = socket(AF_INET, SOCK_STREAM, 0);
    int optval = 1;
    setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
    struct sockaddr_in my_addr = make_server_addr(port);
    if ( s == -1 )
        error("socket()");
    bind(s, (struct sockaddr*)&my_addr, sizeof my_addr);
    listen(s, BACKLOG);
    return s;
}

void get_file_request(int socket, char *fileName)
{
    char buf[BUFSIZ];
    int n = read(socket, buf, BUFSIZ);
    if ( n < 0 )
        error("read from socket");
    buf[n] = '\0';
    strcpy(fileName, buf);
    printf("Server got file name of '%s'\n", fileName);
}

void write_file_to_client_socket(char *file, int socket)
{
    char buf[BUFSIZ];
    int n;
    int ifd = open(file, O_RDONLY);
    if ( ifd == -1 )
        error("open()");
    while ( (n = read(ifd, buf, BUFSIZ)) > 0 )
        write(socket, buf, n);
    close(ifd);
}

void * handle_request(void * c_socket)
{
    int *client_socket = (int*)c_socket;
    char fileName[BUFSIZ];
    get_file_request(*client_socket, fileName);
    write_file_to_client_socket(fileName, *client_socket);
    close(*client_socket);
    pthread_exit(0);
    return NULL;
}

void time_out(int arg)
{
    fprintf(stderr,  "Server timed out\n");
    exit(0);
}

void set_time_out(int seconds)
{
    struct itimerval value = {0};
    // bzero(&value, sizeof value);
    /* timerclear(&value.it_interval); timerclear(&value.it_value); */
    value.it_value.tv_sec = seconds;
    setitimer(ITIMER_REAL, &value, NULL);
    signal(SIGALRM, time_out);
}

void accept_client_requests(int server_socket)
{
    pthread_t threads;
    int client_socket;
    struct sockaddr_in client_addr;
    socklen_t sin_size = sizeof client_addr;
    set_time_out(10);
    while ( (client_socket =
            accept(server_socket, (struct sockaddr*)&client_addr, &sin_size)) )
    {
        set_time_out(10);
        pthread_create(&threads,0, handle_request,&client_socket);
    }
}

int main(int argc, char *argv[])
{
    if ( argc != 2 )
        error("usage: server port");
    short port = atoi(argv[1]);
    int server_socket = create_server_socket(port);
    accept_client_requests(server_socket);
    shutdown(server_socket, 2);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“Timer.h”
#定义待办事项200
//如果队列中的数据超过此值,则客户端连接将失败
#定义NUM_线程200
无效错误(字符*消息)
{
fprintf(stderr,“%s\n”,msg);
出口(-1);
}
make_服务器_addr中的结构sockaddr_(短端口)
{
地址中的结构sockaddr\u;
memset(&addr,0,地址大小);
addr.sin_family=AF_INET;
地址SINU port=htons(端口);
addr.sin\u addr.s\u addr=INADDR\u ANY;
返回地址;
}
int创建\u服务器\u套接字(短端口)
{
int s=套接字(AF_INET,SOCK_STREAM,0);
int optval=1;
setsockopt(s、SOL_插座、SO_REUSEADDR和optval、optval尺寸);
my_addr中的struct sockaddr_=make_server_addr(端口);
如果(s==-1)
错误(“socket()”);
绑定(s,(struct sockaddr*)和我的地址,我的地址的大小);
倾听(s,积压工作);
返回s;
}
无效获取文件请求(int-socket,char*fileName)
{
char buf[BUFSIZ];
int
int client_socket;
pthread_create(&threads,0, handle_request,&client_socket);
int *client_socket = (int *)c_socket;
int *temp = malloc( sizeof(int) );
*temp = client_socket;
pthread_create(&threads, 0, handle_request, temp);
pthread_detach(threads);