argc不是2错误

时间:2015-11-30 01:26:49

标签: c debugging server client

我一直在研究一个类似于我之前在此发布的程序https://stackoverflow.com/questions/33989328/converting-linked-list-array-client-server-into-single-array的程序,除了这次我试着让示例代码在这个过程中制作我自己的程序(相同的基本当我得到这个奇怪的错误时,程序但不同的内容)。在调试器中有一点,如果argc!= 2它是一个用法:客户端主机名错误。我运行了几次,发现argc是1.我如何使argc为2而不是1或3?有一个客户端和服务器程序如下:

编辑现在它说拒绝连接

客户端:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//define constants
#define SERVER_PORT 6500
#define BUFFER_SIZE 1000
void die(const char*);
void pdie(const char *);
int main (int argc, char *argv[]) {
  int sock;                   // file descriptor (fd) for socket connection
  struct sockaddr_in server;  // Socket info for server
  struct sockaddr_in client;  // Socket info about us
  int clientLen;              // length of client socket struct
  struct hostent *hp;         // return value from gethostbyname()
  char buf[BUFFER_SIZE];      // buffer for message reception from server
  int i;                      // loop counter
  if (argc != 2) {
    die("Usage: client hostname");
  }
  for(i = 0; i < 3; i++) {
    // Open a socket unbound with type ip/tcp
    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
      pdie("Opening stream socket");
    }
    puts("created sock");
    // Prepare to connect to server
    memset((char*)&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    if ((hp = gethostbyname(argv[1])) == NULL) {
      char msg[100];
      sprintf(msg, "%s: unknown host\n", argv[1]);
      die(msg);
    }
    puts("prepared to connect to server");
    // set sin_addr struct variables
    memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
    // IP address should be set to that of the machine running the server
    server.sin_addr.s_addr = inet_addr("replace with your ip address");
    server.sin_port = htons((u_short) SERVER_PORT);
    // Try to connect
    socklen_t serverLen = sizeof(server);
    if (connect(sock, (struct sockaddr *) &server, serverLen) < 0) {
      pdie("connecting stream socket");
    }
    // Determine what port client is using
    clientLen = sizeof(client);
    if (getsockname(sock, (struct sockaddr *) &client, &clientLen)) {
      pdie("Getting socket name");
    }
    if (clientLen != sizeof(client)) {
      die("getsocketname() overwrote name structure");
    }
    printf("Client socket has port %hu\n", ntohs(client.sin_port));
    // Prepare our buffer for a read
    memset(buf, 0, sizeof(buf));
    char input[80];
    // get initial prompt
    read(sock, buf, BUFFER_SIZE);
    printf("%s", (char*)buf);
    // get user action choice and send to server
    scanf("%s", input);
    write(sock, (void*)input, strlen(input));
    // control for translation choice
    if (strncmp(input, "t", 1) == 0) {
      // get prompt for word to translate
      read(sock, buf, BUFFER_SIZE);
      printf("%s", (char*)buf);
      // get user word and send to server
      scanf("%s", input);
      write(sock, (void*)input, strlen(input));
      memset(buf, 0, sizeof(buf));
      // get translation
      read(sock, buf, BUFFER_SIZE);
      // output result
      if(strncmp((char*)buf, "ERROR", 5) == 0) {
        printf("%s\n", (char*)buf);
      } else {
        printf("%s in Japanese is %s\n", input, (char*)buf);
      }
    }
    // control for add to dictionary choice
    else if (strncmp(input, "a", 1) == 0) {
      // get prompt for eng word
      memset(buf, 0, sizeof(buf));
      read(sock, buf, BUFFER_SIZE);
      // get eng word from user
      printf("%s", (char*)buf);
      scanf("%s", input);
      // send eng word to server
      write(sock, (void*)input, strlen(input));
      memset(buf, 0, sizeof(buf));
      // get prompt for Japanese word
      read(sock, buf, BUFFER_SIZE);
      printf("%s", (char*)buf);
      scanf("%s", input);
      // send Japanese word to server
      write(sock, (void*)input, strlen(input));
      // get result
      memset(buf, 0, sizeof(buf));
      read(sock, buf, BUFFER_SIZE);
      printf("%s\n", (char*)buf);
    }
    // Close this connection
    close(sock);
  }// end for loop
    exit(0);
}// end main
// Call perror() to figure out what's going on and die
void pdie(const char *mesg) {
  perror(mesg);
  exit(1);
}
// Print a message and die
void die(const char *mesg) {
  fputs(mesg, stderr);
  fputc('\n', stderr);
  exit(1);
}

和服务器

#define _REENTRANT
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/uio.h>
#include <unistd.h>
#include <pthread.h>

// constant declarations
#define TCP_PORT 6500
#define BUFFER_SIZE 1000

// variable declarations
pthread_mutex_t lock;
int serve_count;

// used to store eng word and translation
typedef struct wordpair* wordPairPtr;
struct wordPair
{
    char* eng;
    char* jap;
    wordPairPtr nextPair;
};
typedef struct wordPair wordPair;

// used to store all word pairs in a directory
// implemented as a linked list
struct directory
{
    wordPair* dict;
    int num_words;
};
typedef struct directory directory;

// function prototypes
void* doKid(void*);
void  initializeDirect();
int   directAdd(char*, char*);
char* translate(char*);

// global directory variable
directory* d;

main ()
{
    // variable declarations
    int sockfd;
    int newsockfd;
    int client;
    struct sockaddr_in cli_addr, serv_addr;
    pthread_t chld_thr;
    initializeDirect();// call function to create directory
    puts ("initialized variables");

    // build thread attributes
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    puts("set thread attributes");

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        fprintf(stderr, "server: can't open stream socket\n");
        exit(0);
    }
    puts("opened stream socket");

    // set serv_addr struct variables
    memset((char*) &serv_addr, 0, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(TCP_PORT);
    puts("did serv_addr actions");

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
    {
        fprintf(stderr, "server: can't bind local address\n");
        exit(0);
    }
    puts("bound local address");

    // set the level of thread concurrency we desire
    pthread_setconcurrency(5);
    listen(sockfd, 5);
    puts("set thread concurrency");

    // begin listening for client requests
    puts("awaiting requests");
    for(;;)
    {
        client = sizeof(cli_addr);
        newsockfd = accept(sockfd, (struct sockaddr*) &cli_addr, &client);
        if (newsockfd < 0)
        {
            fprintf(stderr, "server: accept error\n");
            exit(0);
        }

        // create a new thread to process the incoming request
        pthread_create(&chld_thr, &attr, doKid, (void*)newsockfd);
        puts("Created thread");
        // the server is now free to accept another socket request
    }

    free(d);
    puts("now exiting");
    return(0);

}// end main

// allocates memory for directory and stores small set of preloaded words and phrases
void initializeDirect()
{
    d = (directory*)malloc(sizeof(directory));
    if (d == NULL)
    {
        exit(1);
    }
    char *eng[20] =   {"good morning",    "good afternoon",   "good evening",   "good-bye",
                       "good night)",  "thank you",    "no",  "yes",
                       "I'll go and come back", "I'm home", "mother", "father", "older sister", "older brother", "younger sister", "younger brother", "god", "boy", "girl", "spirit"
                      };

    char *jap[20] =   {"ohaiyou",    "konnichiwa",   "konbanwa",   "sayonara",
                       "oyasumi(nasai)",  "arigatou",    "iie",  "hai",
                       "ittekimasu", "tadaima", "okaasan", "otousan", "oneesan", "oniisan", "imouto", "otouto", "kami", "shoenen", "shoujo", "genki"
                      };
    int i;
    for(i = 0; i < 10; i++)
    {
        directAdd(eng[i], jap[i]);
    }
}// end initializeDirect()

// adds a new word pair alphabetically into the directory
int directAdd(char* eng, char* jap)
{
    // test for valid arguments
    if (eng == NULL || jap == NULL)
    {
        return (-1);
    }

    // allocate memory for new wordPair
    wordPair *newPair = (wordPair*)malloc(sizeof(wordPair));
    if(newPair == NULL)
        return(-1);

    // assign passed values to new wordPair
    newPair->eng = eng;
    newPair->jap = jap;
    newPair->nextPair = NULL;

    // if this is the first wordPair, add it to the front of the linked list
    if(d->dict == NULL)
    {
        d->dict = newPair;
        return 0;
    }

    // otherwise, search directory for correct location for new word pair
    wordPair *current = d->dict;
    wordPair *previous = NULL;

    while(current != NULL && (strcasecmp(current->eng, newPair->eng) < 0))
    {
        previous = current;
        current = current->nextPair;
    }

    // if the new word is last in the directory, add it there
    if(current == NULL)
    {
        previous->nextPair = newPair;
        return 0;
    }
    // if the english word is already in the directory, return -2
    if(strcasecmp(current->eng, newPair->eng) == 0)
    {
        free(newPair);
        return -2;
    }

    // if the new word is first in the directory, add it there
    if(previous == NULL)
    {
        newPair->nextPair = d->dict;
        d->dict = newPair;
        return;
    }

    // if none of the special cases occurred, add the new word
    newPair->nextPair = current;
    previous->nextPair = newPair;

    // advance total count of words
    d->num_words++;

    // return success
    return 0;
}

char* translate(char* eng)
{
    // check that our directory is valid
    if (d == NULL || d->dict == NULL)
        return NULL;

    // start searching at the beginning of the directory
    wordPair *current = d->dict;
    // loop until we find the word or reach the end of the directory
    while(current != NULL && strcasecmp(current->eng, eng) < 0)
    {
        current = current->nextPair;
    }
    // the word is not in the directory
    if(current == NULL)
    {
        return NULL;
    }
    // we found the word, return the translation
    if( strcasecmp(current->eng, eng) == 0)
    {
        return strdup(current->jap);
    }

    // there was an error, return null
    return NULL;
}// end translate

// this is the routine that is executed from a new thread
void *doKid(void* arg)
{
    int mysocfd = (int) arg;
    char buf[BUFFER_SIZE];
    char *eng;
    char *jap;
    char *msg;
    int i;

    // allocate strings
    memset(buf, 0, BUFFER_SIZE);
    eng  = (char*)malloc(sizeof(char[20]));
    jap = (char*)malloc(sizeof(char[20]));
    msg  = (char*)malloc(sizeof(char[100]));

    // build and send intro prompt for client
    msg = "Would you like to translate or add a word? (t/a): ";
    write(mysocfd, (void*)msg, strlen(msg));

    // read from the given socket
    read(mysocfd, buf, BUFFER_SIZE);

    // if the client wants to translate a word
    if(strncmp((char*)buf, "t", 1) == 0)
    {
        // build and send prompt for word to translate
        msg = "Enter the English word you would like to translate to jap: ";
        write(mysocfd, (void*)msg, strlen(msg));
        // receive word
        read(mysocfd, buf, BUFFER_SIZE);
        strcpy(eng, buf);
        // execute translation
        char *trans;
        trans = (char*)malloc(sizeof(char[20]));
        // lock global variable for read
        pthread_mutex_lock(&lock);
        trans = translate((char*)buf);
        pthread_mutex_unlock(&lock);
        // if word was not in directory send error msg to client
        if (trans == NULL)
        {
            msg = "ERROR: word is not in the directory.";
            write(mysocfd, (void*)msg, strlen(msg));
        }
        // if word was translated, send result to client
        else
        {
            write(mysocfd, (void*)trans, strlen(trans));
        }
    }
    // if the client wants to add a word
    else if (strncmp((char*)buf, "a", 1) == 0)
    {
        // build and send prompt for english word
        msg = "Enter the English word to add: ";
        write(mysocfd, (void*)msg, strlen(msg));
        // receive word
        read(mysocfd, buf, BUFFER_SIZE);
        strcpy(eng, buf);
        // build and send prompt for jap translation
        memset(buf, 0, sizeof(buf));
        msg = "Enter the translation to jap: ";
        write(mysocfd, (void*)msg, strlen(msg));
        // receive translation
        memset(buf, 0, sizeof(buf));
        read(mysocfd, buf, BUFFER_SIZE);
        strcpy(jap, buf);
        // lock global variable for word insertion
        pthread_mutex_lock(&lock);
        int result = directAdd(eng, jap);
        pthread_mutex_unlock(&lock);
        // if the add to directory was successful, alert client
        if (result == 0)
        {
            msg = "Added to directory";
        }
        // if the add to directory was unsuccessful send client error msg
        else if (result == -2)
        {
            msg = "Word is already in directory";
        }
        else
        {
            msg = "ERROR.";
        }
        write(mysocfd, (void*)msg, strlen(msg));
    }
    // if no valid choice was sent by client, exit thread
    else
    {
        close(mysocfd);
        pthread_exit(0);
    }

    printf("Child[%lu]: Done Processing...\n", pthread_self());

    // use a mutex to update the global service counter
    pthread_mutex_lock(&lock);
    serve_count++;
    pthread_mutex_unlock(&lock);

    printf("Kid thread [%lu]: The total sockets served = %d\n", pthread_self(), serve_count);

    // close the socket and exit this thread
    close(mysocfd);
    pthread_exit(0);

}// end doKid()

0 个答案:

没有答案