Posix服务器 - 客户端应用程序在通信期间陷入困境

时间:2016-06-20 20:46:52

标签: c unix client-server posix

我正在学习posix标准中的C.我正在尝试创建客户端 - 服务器应用程序,现在我尝试处理它们之间的通信。

我不知道如何让客户知道他什么时候应该向服务器发送内容。我想出的很简单 - 当服务器发送消息“1”时,它意味着它现在等待客户端的输入。

我首先尝试使用telnet,但它在某种程度上有效。当我创建客户端应用程序时出现问题 - 它工作在ONCE。后来它决定停止工作。服务器正确地从客户端获取一个输入(当他选择“AddObject”选项时),然后它停止工作(客户端不知道服务器等待消息)。

我试图尽可能地清理我的代码(我的实际代码是一个巨大的,因为我经常尝试不同的东西,并有很多评论),但它可能很糟糕 - 对不起。

服务器

#define _GNU_SOURCE 
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdbool.h>
#include <poll.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <ctype.h>

#define maxnamel 50
#define BUFLEN 512
#define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
                     perror(source),kill(0,SIGKILL),\
                         exit(EXIT_FAILURE))

struct arg_struct {
    int fd;
    int org;
};

void usage(void);
int make_socket(uint16_t port);                  


void usage(void){
    fprintf(stderr, "Usage: ./all\n");
    exit(EXIT_FAILURE);
}


void sendAndPrint(char* wiadomosc, int sock){

    write((int)sock , wiadomosc , strlen(wiadomosc));
    printf("%s",wiadomosc);
}


int make_socket(uint16_t port) {
    struct sockaddr_in name;
    int sock, t=1;

    sock = socket(PF_INET,SOCK_STREAM,0);

    if (sock < 0) ERR("socket");

    name.sin_family = AF_INET;
    name.sin_port = htons(port);
    name.sin_addr.s_addr = htonl(INADDR_ANY);

    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(t))) ERR("setsockopt");
    if (bind(sock,(struct sockaddr*) &name, sizeof(name)) < 0) ERR("bind");
    return sock;
}

void addObject (int sock)
{
    int read_size, read_size_sum;
    char* buf;
    char *record;
    record=malloc(sizeof(char)*100+1);

    buf=malloc(sizeof(char)*10+1);
    sendAndPrint("AddObject.\n", sock);
    sendAndPrint("Add details of new object.\n", sock);
    sendAndPrint("Name:\n", sock);
    sleep(0.5);
    sendAndPrint("1", sock);
    read_size = recv(sock, buf, maxnamel, 0);
    printf("%s", buf);
    read_size-=1;
    buf[read_size]=0;
    read_size_sum = read_size;
    strcpy(record,buf); 

    record[read_size-1]=0;

    sendAndPrint("Age:\n", sock);
    sendAndPrint("1\n", sock);
    read_size = recv(sock, buf, 10, 0);
    read_size-=1;
    buf[read_size+1]=0;
    read_size_sum +=read_size;
    strcat(record,"-");
    strcat(record,buf);

    record[read_size_sum-2]=0;

    sendAndPrint("Weight:\n", sock);
    sendAndPrint("1", sock);
    read_size = recv(sock, buf, 10, 0);
    buf[read_size-1]=0;
    read_size_sum +=read_size;
    strcat(record,"-");
    strcat(record,buf);
    record[read_size_sum-3]=0;

    sendAndPrint("Number:\n", sock);
    sendAndPrint("1", sock);
    read_size = recv(sock, buf, 10, 0);
    buf[read_size-1]=0;
    read_size_sum +=read_size;
    strcat(record,"-");
    strcat(record,buf);
    record[read_size_sum-3]=0;

    strcat(record,"-0");
    strcat(record,"\n");

}

void *connection_handler(void *sock_desc)
{
    return 0;
}

void *organizer_handler(void *sock_desc)
{
    int wybor, read_size;
    char client_message[1000];
    int sock = *(int*)sock_desc;


    sendAndPrint("Start.\n",sock);
    sendAndPrint("Choose your action:\n\n1 - Add Object\n2 - To Do\n3 - To Do\n",sock);
    sendAndPrint("4 - To Do\n\n\n", sock);
    sendAndPrint("1", sock);
    while((read_size = recv(sock , client_message , 100 , 0)) > 0 )
    {


        wybor=atoi(client_message);

        if((wybor==1))
            addObject(sock);
        else
            {
                sendAndPrint("Wrong choice.\n\n",sock);
                sleep(3);
            }


        sendAndPrint("Choose your action:\n\n1 - Add Object\n2 - To Do\n3 - To Do\n",sock);
        sendAndPrint("4 - To Do\n\n\n", sock);
    }
    return 0;
}


void *doClient(void *arguments){

    struct arg_struct *args = arguments;

    int fd = args -> fd;
    int org = args -> org;

    int backlog=10; 
    int l, c,client_sock, *new_sock;
    fd_set set;
    pthread_t sniffer_thread2;

    struct sockaddr_in client;
    l=listen(fd, backlog);
    c = sizeof(struct sockaddr_in);

    puts("Thread created.");


    while(1)
    {

    FD_ZERO(&set);
    FD_SET (fd, &set);
    puts("Waiting for connection...");

    while((client_sock = accept(fd, (struct sockaddr *)&client, (socklen_t*)&c)))
        {           


            new_sock = malloc(1);
            *new_sock = client_sock;

            if (org == 1)
            { 

                puts("Organizer has connected. Creating thread...");
                if( pthread_create( &sniffer_thread2 , NULL ,  organizer_handler , (void*) new_sock) < 0)
                {
                    perror("Could not create thread for organizer.");
                    return 0;
                }
            } else
            {
                puts("Normal client has connected. Creating thread...");
                if( pthread_create( &sniffer_thread2 , NULL ,  connection_handler , (void*) new_sock) < 0)
                {
                    perror("Could not create thread for normal client.");
                    return 0;
                }
            }
        }

    }

    return 0;
}

void doServer(int fd){

    pthread_t sniffer_thread;
    char message[1000];
    struct arg_struct orgArgs;

    orgArgs.fd = fd;
    orgArgs.org = 1;

    puts("Started server.");
    puts("Creating a thread for organizer client...");

    if( pthread_create( &sniffer_thread , NULL ,  doClient , (void *)&orgArgs) < 0)
            {
                perror("Could not create thread for doClient for organizers.");
                return;
            }

        puts("Type 1 if you want to stop server.");
        while (scanf("%s", message))
        {
            if(atoi(message) == 1)
        {
            puts("Closing server.");
            break;
        }
        else
            puts("Type 1 if you want to stop server.");
        }   
}

int main(int argc, char** argv) {
    int fd;
    uint16_t port=8089;

    if(argc != 1){
        usage();
    }

    fd = make_socket(port);

    doServer(fd);

    return EXIT_SUCCESS;
}

客户端

#define _GNU_SOURCE 
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#include <stdbool.h>
#include <poll.h>
#include <netdb.h>

#define HERR(source) (fprintf(stderr,"%s(%d) at %s:%d\n",source,h_errno,__FILE__,__LINE__),\
             exit(EXIT_FAILURE))
#define BUFLEN 512
#define ERR(source) (fprintf(stderr,"%s:%d\n",__FILE__,__LINE__),\
                     perror(source),kill(0,SIGKILL),\
                         exit(EXIT_FAILURE))

int fd;

int make_socket(void){
    int sock;
    sock = socket(PF_INET,SOCK_STREAM,0);
    if(sock < 0) ERR("socket");
    return sock;
}

struct sockaddr_in make_address(uint16_t port){
    struct sockaddr_in addr;
    struct hostent *hostinfo;
    addr.sin_family = AF_INET;
    addr.sin_port = htons (port);
    hostinfo = gethostbyname("localhost");
    if(hostinfo == NULL)HERR("gethostbyname");
    addr.sin_addr = *(struct in_addr*) hostinfo->h_addr;
    return addr;
}

int connect_socket(uint16_t port){
    struct sockaddr_in addr;
    int socketfd;
    socketfd = make_socket();
    addr=make_address(port);
    if(connect(socketfd,(struct sockaddr*) &addr,sizeof(struct sockaddr_in)) < 0){
        if(errno!=EINTR) ERR("connect");
        else { 
            fd_set wfds;
            int status;
            socklen_t size = sizeof(int);
            FD_ZERO(&wfds);
            FD_SET(socketfd, &wfds);
            if(TEMP_FAILURE_RETRY(select(socketfd+1,NULL,&wfds,NULL,NULL))<0) ERR("select");
            if(getsockopt(socketfd,SOL_SOCKET,SO_ERROR,&status,&size)<0) ERR("getsockopt");
            if(0!=status) ERR("connect");
        }
    }
    return socketfd;
}

void doClientORG(int fd){
    int read_size;
    int msg_size;
    char client_message[1000];
    char message[1000];

    puts("Waiting for server.");
    while((read_size = recv(fd , client_message , 100 , 0)) > 0 )
    {
        client_message[read_size]=0;
        if(atoi(client_message) == 1)
        {
            puts("Inside");
            scanf("%s", message);

            /*printf("Message: %s\n\n", message);*/
            write(fd, message,1);

        }
        else
            printf("%s", client_message);
    }
}

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

    int fd;
    uint16_t port=8089;
    char* message;
    fd=connect_socket(port);


    doClientORG(fd);
    return EXIT_SUCCESS;
}

有什么想法吗?我做错了什么,或者我的想法开头是不正确的?

0 个答案:

没有答案