遇到C套接字程序陷入困境

时间:2017-11-03 00:24:47

标签: c sockets

我目前正在研究服务器 - 客户端对,它会在发送到服务器时拼写检查txt文件,但我的代码只是在中途挂起。希望有不同观点的人可以告诉我我没有看到的东西。这是服务器代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>

int main(int argc, char *argv[]){
  int welcomeSocket, newSocket;
  char *dictionary[100000];
  char buffer[1024];
  struct sockaddr_in serverAddr;
  struct sockaddr_storage serverStorage;
  socklen_t addr_size;

//create socket. 0 means TCP
welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
//address family -> internet
serverAddr.sin_family = AF_INET;
//set port number using htons for byte ordering
serverAddr.sin_port = htons(19703);
//set IP to localhost
serverAddr.sin_addr.s_addr=htonl(INADDR_ANY); //any IP
//set bits of the padding field to 0
memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
//bind address to the socket
bind(welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr));
//listen on socket 19703, max 5 connections queued
if(listen(welcomeSocket,5) == 0)
  printf("Listening...\n");
else
  printf("Error\n");

//copy dictionary to array
  FILE *fp;
  char temp[100];
  fp = fopen(argv[1], "r");
  int pos = 0;
  while(fgets(temp, 1024, fp) != NULL){
      strtok(temp, "\n");     //remove trailing newline
      dictionary[pos] = temp;
      pos++;
  }

//accept creates a new socket for the incoming connection
addr_size = sizeof serverStorage;
newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
printf("accepted...\n");

//receive word from client
  read(newSocket, buffer, 1024);
printf("read...\n");
//spit it back out (used in testing and debugging
  printf("The word is: %s", buffer);

//search dictionary array
  int i=0;
  int good=0;
  while(dictionary[i] != NULL){
    if(strcmp(buffer, dictionary[i])==0){
      printf("%s - OK\n", buffer);
      good++;
      i++;
    }
  }
if(good == 0){
  printf("%s - MISSPELLED\n", buffer);
}
  return 0;
}//end main

正如您所看到的,我有一些用于调试的printf语句。为了告诉你它挂起的地方(奇怪的地方)我在客户端发送时得到的输出是:

Listening...
accepted...
read...

我无法说明为什么会这样。感谢任何能够解决问题的人。我正在为这个工作做更多的工作,因为我仍然需要实现多线程和信号量和东西。

1 个答案:

答案 0 :(得分:0)

以下提议的代码:

  1. 更正了评论中列出的问题
  2. 执行所需的功能
  3. 干净地编译
  4. 尚未经过测试
  5. 正确检查错误
  6. 将其留给OP,以便在每次调用exit()
  7. 之前插入代码进行清理

    现在建议的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <sys/socket.h>   // socket()
    #include <netinet/in.h>
    #include <string.h>
    
    #define MAX_DICTIONARY_ENTRIES 100000
    #define MAX_BUFFER_LEN         1024
    #define MAX_TEMP_BUF           100
    
    
    int main( int argc, char *argv[] )
    {
        int welcomeSocket;
        int newSocket;
    
        char *dictionary[ MAX_DICTIONARY_ENTRIES ] = {NULL};
        char buffer[ MAX_BUFFER_LEN +1]; // plus 1 to allow for NUL terminator byte
    
        struct sockaddr_in serverAddr;
        struct sockaddr_storage serverStorage;
        socklen_t addr_size;
    
        if( 2 != argc )
        {
            fprintf( stderr, "USAGE: %s <dictionaryFileName>\n", argv[0] );
            exit( EXIT_FAILURE );
        }
    
        // implied else, correct number of arguments
    
        //create socket. 0 means TCP
        welcomeSocket = socket(PF_INET, SOCK_STREAM, 0);
        if( 0 > welcomeSocket )
        {
            perror( "socket failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, socket successful
    
        //address family -> internet
        serverAddr.sin_family = AF_INET;
    
        //set port number using htons for byte ordering
        serverAddr.sin_port = htons(19703);
    
        //set IP to localhost
        serverAddr.sin_addr.s_addr=htonl(INADDR_ANY); //any IP
    
        //set bits of the padding field to 0
        memset(serverAddr.sin_zero, '\0', sizeof serverAddr.sin_zero);
    
        //bind address to the socket
        if( 0 != bind( welcomeSocket, (struct sockaddr *) &serverAddr, sizeof(serverAddr) ) )
        {
            perror( "bind failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, bind successful
    
        //listen on socket 19703, max 5 connections queued
        if( listen( welcomeSocket, 5 ) != 0 )
        {
            perror( "listen failed" );
            printf("Error\n");
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, listen successful
    
        printf( "listening...\n" );
    
        //copy dictionary to array
        FILE *fp;
        char temp[ MAX_TEMP_BUF ];
        fp = fopen(argv[1], "r");
        if( !fp )
        {
            perror( "fopen failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, fopen successful
    
        size_t pos = 0;
        while( pos < (sizeof dictionary / sizeof dictionary[0])
            && fgets( temp, sizeof temp, fp ) )
        {
            strtok(temp, "\n");     //remove trailing newline
            dictionary[pos] = strdup(temp);
            if( !dictionary[pos] )
            {
                perror( "strdup failed" );
                // TODO: cleanup
                exit( EXIT_FAILURE );
            }
    
            // implied else, strdup successful
    
            pos++;
        }
    
        fclose( fp );
    
        //accept creates a new socket for the incoming connection
        addr_size = sizeof serverStorage;
        newSocket = accept(welcomeSocket, (struct sockaddr *) &serverStorage, &addr_size);
        if( 0<= newSocket )
        {
            perror( "accept failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, accept successful
    
        printf("accepted...\n");
    
        //receive word from client
        ssize_t bytesread = read(newSocket, buffer, sizeof buffer);
        if( 0 >= bytesread )
        {
            perror( "read failed" );
            // TODO: cleanup
            exit( EXIT_FAILURE );
        }
    
        // implied else, read successful
    
        buffer[bytesread] = '\0';  // terminate the string
        printf("read...\n");
    
        //spit it back out (used in testing and debugging
        printf("The word is: %s\n", buffer);
    
        //search dictionary array
        int good=0;
        for( size_t i=0; dictionary[i] != NULL; i++)
        {
            if(strcmp(buffer, dictionary[i])==0)
            {
                printf("%s - OK\n", buffer);
                good++;
                break; // exit 'for()' loop
            }
        }
    
        if( !good )
        {
            printf("%s - not found in dictionary\n", buffer);
        }
    
        close( welcomeSocket );
        close( newSocket );
    
        // TODO: other cleanup
    
    
        return 0;
    }//end main