Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/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
C socket命令打开一个文件并将输出发送到客户端_C_Sockets_Network Programming - Fatal编程技术网

C socket命令打开一个文件并将输出发送到客户端

C socket命令打开一个文件并将输出发送到客户端,c,sockets,network-programming,C,Sockets,Network Programming,因此,我在局域网的一台计算机上有一个client.c文件,在另一台计算机上有一个server.c文件。本质上,我启动server.c文件并指定它在等待时需要侦听的端口。我想通过指定服务器正在运行的地址和发送命令的端口来运行client.c命令。我的客户端只发送一个文件名(称之为test.txt)。然后,我的服务器将使用C套接字协议中的recv()接受该命令,我希望能够读取该文件并将该输出发送回我的客户机,以便它输出到我的客户机终端。我已经知道了如何发送文件,因为这很容易,但我很难理解如何使用套接

因此,我在局域网的一台计算机上有一个client.c文件,在另一台计算机上有一个server.c文件。本质上,我启动server.c文件并指定它在等待时需要侦听的端口。我想通过指定服务器正在运行的地址和发送命令的端口来运行client.c命令。我的客户端只发送一个文件名(称之为test.txt)。然后,我的服务器将使用C套接字协议中的recv()接受该命令,我希望能够读取该文件并将该输出发送回我的客户机,以便它输出到我的客户机终端。我已经知道了如何发送文件,因为这很容易,但我很难理解如何使用套接字完成这项任务。我是否只需要使用send()发出写命令?我需要读取文件并逐行发送到套接字吗?如果是这样的话,假设我有10个客户端,那么我是否需要使用信号量或互斥量来确保在转到下一个客户端请求之前完全发送输出

这段代码不仅仅是我想要的,它还有一个日志功能。我一直在使用 作为向导。但它只是将server.c机器上的文件内容发送回client.c输出,这让我有些不知所措

所以理论上,在客户端应该是这样的

./client 129.65.128.82:4443 bigfile
...entire contents of bigfile should appear here...
这是我的Server.c代码和Client.c(在底部供参考)

服务器.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <sys/stat.h>

#define PORT "4443" // the port users will be connecting to

#define BACKLOG 10 // how many pending connections queue will hold

size_t getFilesize(const char* filename) {
    struct stat st;
    if(stat(filename, &st) != 0) {
        return 0;
    }
    return st.st_size;   
}


void fileOutput(char *filename){
    FILE *fptr;
    char c;
    //int check = checkFilename(filename);

    fptr = fopen(filename,"r");
    printf("We opened the file\n");
    if (fptr == NULL)
        {
            printf("Cannot open file \n");
            exit(0);
        }
        printf("HereWe ARE\n");
        // Read contents from file
        c = fgetc(fptr);
        while (c != EOF)
        {           
            printf ("%c", c);
            c = fgetc(fptr);
        }
    fclose(fptr);
}

void sigchld_handler(int s)
{
    (void)s; // quiet unused variable warning

    // waitpid() might overwrite errno, so we save and restore it:
    int saved_errno = errno;

    while ( waitpid(-1, NULL, WNOHANG) > 0 );

    errno = saved_errno;
}

void argumentCheck(int n){
    if (n < 2) {
        fprintf(stderr,"Usage: server port # example port 4443\n");
        exit(1);
    }
}
// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if ( sa->sa_family == AF_INET ) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


void logfile(FILE *fp,char *s,char *port,char *buffer,int r){
    time_t t = time((time_t*) NULL);
    struct tm *tm = localtime(&t);
    char tc[256];
    strftime(tc, 256, "%Y-%m-%d %H:%M:%S", tm);
    fprintf(fp,"[%s] %s:%s %s %d\n",tc,s,port,buffer,r);
}


int main(int argc, char **argv)
{

    //Log file creation
    FILE *fp;
    fp = fopen("log","a");
    ///////


    ///File Size///
    //////////////



    argumentCheck(argc);
    int sockfd, new_fd;  // listen on sockfd, new connection on new_fd
    struct addrinfo hints, *servinfo, *p;
    struct sockaddr_storage their_addr; // connector's address information
    socklen_t sin_size;
    struct sigaction sa;
    int yes=1;
    char s[INET6_ADDRSTRLEN];
    int rv;
    char *inputPort = argv[1];


    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE; // use my IP

    if ( (rv = getaddrinfo(NULL, inputPort, &hints, &servinfo)) != 0 ) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }

    // loop through all the results and bind to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ( (sockfd = socket(p->ai_family, p->ai_socktype,
                p->ai_protocol)) == -1 ) {
            perror("server: socket");
            continue;
        }

        if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
                sizeof(int)) == -1 ) {
            perror("setsockopt");
            exit(1);
        }

        if ( bind(sockfd, p->ai_addr, p->ai_addrlen) == -1 ) {
            close(sockfd);
            perror("server: bind");
            continue;
        }

        break;
    }

    freeaddrinfo(servinfo); // all done with this structure

    if ( p == NULL )  {
        fprintf(stderr, "server: failed to bind\n");
        exit(1);
    }

    // listen allows queue of up to BACKLOG number
    if ( listen(sockfd, BACKLOG) == -1 ) {
        perror("listen");
        exit(1);
    }

    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if ( sigaction(SIGCHLD, &sa, NULL) == -1 ) {
        perror("sigaction");
        exit(1);
    }

    printf("server: waiting for connections...\n");

    while ( 1 ) {  // main accept() loop
        sin_size = sizeof their_addr;
        new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
        if ( new_fd == -1 ) {
            perror("accept");
            continue;
        }
        inet_ntop(their_addr.ss_family,
            get_in_addr((struct sockaddr *)&their_addr),
            s, sizeof s);
        //printf("server: got connection from %s\n", s);


        if ( !fork() ) { // this is the child process
            char buf[1024];
            close(sockfd); // child doesn't need the listener
            printf("this is the sizeof buf %ld\n",sizeof(buf));
            recv(new_fd,buf, sizeof(buf),0);
            int size = getFilesize(buf);
            logfile(fp,s,inputPort,buf,size);
            fileOutput(buf);
 
           if ( send(new_fd, buf, size, 0) == -1)
               perror("send");
            printf("%s\n",buf);
            close(new_fd);
            exit(0);
        }
       close(new_fd);  // parent doesn't need this
    }
    fclose(fp);
    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义端口“4443”//用户将连接到的端口
#定义BACKLOG 10//队列将容纳多少个挂起的连接
大小\u t getFilesize(常量字符*文件名){
结构统计;
如果(stat(filename,&st)!=0){
返回0;
}
返回st.st_大小;
}
无效文件输出(字符*文件名){
文件*fptr;
字符c;
//int check=checkFilename(文件名);
fptr=fopen(文件名,“r”);
printf(“我们打开了文件”\n);
如果(fptr==NULL)
{
printf(“无法打开文件\n”);
出口(0);
}
printf(“我们在此\n”);
//从文件中读取内容
c=fgetc(fptr);
而(c!=EOF)
{           
printf(“%c”,c);
c=fgetc(fptr);
}
fclose(fptr);
}
void sigchld_处理程序(int s)
{
(void)s;//静默未使用的变量警告
//waitpid()可能会覆盖errno,因此我们保存并还原它:
int saved_errno=errno;
而(waitpid(-1,NULL,WNOHANG)>0);
errno=已保存\u errno;
}
无效参数检查(int n){
if(n<2){
fprintf(stderr,“用法:服务器端口#示例端口4443\n”);
出口(1);
}
}
//获取sockaddr、IPv4或IPv6:
void*get\u in\u addr(结构sockaddr*sa)
{
如果(sa->sa_族==AF_INET){
return&(((struct sockaddr_in*)sa)->sin_addr);
}
返回((结构sockaddr_in6*)sa)->sin6_addr);
}
无效日志文件(文件*fp,字符*s,字符*端口,字符*缓冲区,整数r){
time\u t=时间((time\u t*)空值);
struct tm*tm=本地时间(&t);
字符tc[256];
strftime(tc,256,“%Y-%m-%d%H:%m:%S”,tm);
fprintf(fp,[%s]%s:%s%s%d\n),tc,s,端口,缓冲区,r);
}
int main(int argc,字符**argv)
{
//日志文件创建
文件*fp;
fp=fopen(“log”,“a”);
///////
///文件大小///
//////////////
argumentCheck(argc);
int sockfd,new_fd;//在sockfd上侦听,在new_fd上新建连接
结构addrinfo提示,*servinfo,*p;
struct sockaddr\u存储它们的地址;//连接器的地址信息
袜子的大小;
struct-sigaction-sa;
int yes=1;
字符s[INET6_ADDRSTRLEN];
int-rv;
char*inputPort=argv[1];
memset(提示和提示,0,提示大小);
hits.ai_family=AF_unsec;
hits.ai_socktype=SOCK_流;
hits.ai_flags=ai_PASSIVE;//使用我的IP
if((rv=getaddrinfo(NULL、inputPort、提示和服务信息))!=0){
fprintf(标准,“getaddrinfo:%s\n”,gai_strerror(rv));
返回1;
}
//循环遍历所有结果并绑定到第一个结果
for(p=servinfo;p!=NULL;p=p->ai_next){
如果((sockfd=socket(p->ai_族,p->ai_socktype,
p->ai_协议)=-1){
perror(“服务器:套接字”);
继续;
}
如果(设置sockopt)(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,
sizeof(int))==-1){
perror(“setsockopt”);
出口(1);
}
如果(绑定(sockfd,p->ai_addr,p->ai_addrlen)=-1){
关闭(sockfd);
perror(“服务器:绑定”);
继续;
}
打破
}
freeaddrinfo(servinfo);//所有操作都使用此结构完成
if(p==NULL){
fprintf(stderr,“服务器:绑定失败\n”);
出口(1);
}
//listen允许最多为待办事项数量的队列
如果(侦听(sockfd,BACKLOG)=-1){
佩罗尔(“倾听”);
出口(1);
}
sa.sa_handler=sigchld_handler;//获取所有死进程
sigemptyset(和sa.sa_面具);
sa.sa_标志=sa_重启;
if(sigaction(SIGCHLD,&sa,NULL)=-1){
佩罗尔(“sigaction”);
出口(1);
}
printf(“服务器:正在等待连接…\n”);
while(1){//main accept()循环
sin_size=其地址的大小;
新地址=接受(sockfd,(结构sockaddr*)及其地址和大小);
如果(新的_fd==-1){
佩罗(“接受”);
继续;
}
inet_ntop(他们的地址、家庭、,
获取地址((struct sockaddr*)及其地址,
s、 尺寸(s);
//printf(“服务器:已从%s获得连接\n”,s);
如果(!fork()){//这是子进程
char-buf[1024];
close(sockfd);//孩子不需要侦听器
printf(“这是buf%ld\n的大小”,sizeof(buf));
recv(新财务总监,财务总监)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>

#include <arpa/inet.h>

#define PORT "4443" // the port client will be connecting to

// get sockaddr, IPv4 or IPv6:
void *get_in_addr(struct sockaddr *sa)
{
    if ( sa->sa_family == AF_INET ) {
        return &(((struct sockaddr_in*)sa)->sin_addr);
    }

    return &(((struct sockaddr_in6*)sa)->sin6_addr);
}


int main(int argc, char **argv)
{
    if ( argc < 2 ) {
        fprintf(stderr,"Usage: client ipaddr:port # example 129.65.128.82:4443 [filename]\n");
        exit(1);
    }

    int sockfd, numbytes;
    char buf[BUFSIZ];
    struct addrinfo hints, *servinfo, *p;
    int rv;
    char s[INET_ADDRSTRLEN];

// Used to extract ipv4 and socket seperatly
    char *ip_address = strtok(argv[1],":");
    char *ip_port = strtok(NULL,":");

    memset(&hints, 0, sizeof(hints));  // make sure the struct is empty
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ( (rv = getaddrinfo(ip_address, ip_port, &hints, &servinfo)) != 0 ) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return 1;
    }


    // loop through all the results and connect to the first we can
    for(p = servinfo; p != NULL; p = p->ai_next) {
        if ( (sockfd = socket(p->ai_family,
                          p->ai_socktype,
                          p->ai_protocol)) == -1 ) {
            perror("client: socket");
            continue;
        }

        if ( connect(sockfd, p->ai_addr, p->ai_addrlen) == -1 ) {
            perror("client: connect");
            close(sockfd);
            continue;
        }

        break;
    }

    if ( p == NULL ) {
        fprintf(stderr, "client: failed to connect\n");
        return 2;
    }
    //printf("we are stopping here");
    inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
        s, sizeof s);
    printf("client: connecting to %s\n", s);

    freeaddrinfo(servinfo); // all done with this structure

    //strcpy(buf, "Hello World.\n");
    //printf("this is argv2 size %ld\n",strlen(argv[2]));
    strcpy(buf,argv[2]);
    //printf("this is buf size %ld\n",strlen(buf));
    //write(1, "client send: ", strlen("client send: "));
    //write(1, buf, strlen(buf));

    send(sockfd, buf, sizeof(buf), 0);


    if ( (numbytes = recv(sockfd, buf, sizeof(buf)-1, 0)) == -1 ) {
        printf("this is numbytes %d\n",numbytes);
        perror("recv");
        exit(1);
    }
    printf("this is numbytes %d\n",numbytes);
    buf[numbytes] = '\0';

    //write(1, "client recv: ", strlen("client recv: "));
    //write(1, buf, strlen(buf));

    close(sockfd);

    return 0;
}


enter code here