聊天服务器(C语言中的网络编程)

时间:2016-04-25 15:45:48

标签: c sockets tcp network-programming

我在c中制作了以下聊天服务器程序。问题是,一旦我运行我的客户端并且客户端屏幕上显示“客户端说: - ”,服务器立即显示“客户端说: - ”,“服务器说: - ”而不等待客户端给出输入然后处理它,无论我输入什么,程序都不起作用。

我希望我的客户端请求输入然后将其发送到服务器,然后服务器应显示客户端的输入并询问它自己的输入。这应该继续,直到他们中的任何人进入'再见'。

//聊天服务器

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

int main()
{
   int sockfd = socket(AF_INET,SOCK_STREAM,0);

   if(sockfd<0)
   {
    perror("Error in Creating Socket\n");
    exit(-1);
   }

   struct sockaddr_in server,client;

   bzero(&server,sizeof(server));
   server.sin_family = AF_INET;
   server.sin_port = htons(10000);
   server.sin_addr.s_addr = INADDR_ANY;



   if(bind(sockfd, (struct sockaddr*)&server, sizeof(server))<0)
   {
       perror("Error in Socket Binding\n");
       exit(-1);
   }

   if(listen(sockfd,5)<0)
   {
    perror("Error in Listening\n");
    exit(-1);
   }

   printf("Listening\n");

   char clientsent[500];
   char bhago[5] = "exit";
   bhago[5] = '\0';
   char serverinput[500];

   while(1)
   {
    int acceptfd = accept(sockfd, (struct sockaddr*)&client, (socklen_t*)sizeof(client));

    pid_t pid = fork();

    if(pid == 0)//child process is executing
    {  

        close(sockfd);

        while(1)
        {

            bzero(&serverinput, 500);
            bzero(&clientsent, 500);

            int n = recv(acceptfd, clientsent,500,0);

            printf("Client Says :-\n");
            printf("%s",clientsent);


            if(strcmp(clientsent,bhago) == 0)
            {
                close(acceptfd);
                exit(0);
            }


            printf("Server Says :-\n");

            int x = 0;

            do{

                serverinput[x]=getchar();
                x++;
              }while(x-1 != '\n');

            send(acceptfd, serverinput, 500, 0);

            if(strcmp(serverinput,bhago) == 0)
            {
                close(acceptfd);
                exit(0);
            }

        }
    }
    close(acceptfd);
   }
}

//聊天客户端

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

int main()
{

   int sockfd = socket(AF_INET,SOCK_STREAM,0);

   if(sockfd<0)
   {
    perror("Error in Creating Socket\n");
    exit(-1);
   }

   struct sockaddr_in server;

   bzero(&server,sizeof(server));
   server.sin_family = AF_INET;
   server.sin_port = htons(10000);
   server.sin_addr.s_addr = INADDR_ANY;

   if(connect(sockfd, (struct sockaddr*)&server, sizeof(server))<0)
   {
    perror("Error in Connection\n");
    exit(-1);
   }

   printf("Connection Established\n");

   char clientinput[500];
   char bhago[5] = "exit";
   bhago[5] = '\0';
   char serversent[500];

   while(1)
   {

    bzero(&clientinput, 500);
    bzero(&serversent, 500);

    printf("Client Says :-\n");

    int x = 0;
    do{

        clientinput[x]=getchar();
        x++;
          }while(x-1 != '\n');

        send(sockfd, clientinput, 500, 0);

        if(strcmp(clientinput, bhago) == 0)
        {
            close(sockfd);
            exit(0);
        }

        printf("Server Said :-\n");

        recv(sockfd, serversent, 500,0);

        printf("%s",serversent);

        if(strcmp(serversent, bhago) == 0)
        {
            close(sockfd);
            exit(0);
        }
   }
close(sockfd);
}//main

1 个答案:

答案 0 :(得分:1)

对于初学者来说,这两行中的后者

char bhago[5] = "exit";
bhago[5] = '\0';

通过访问第6个元素写出bhago的边界来调用未定义的行为,bhago是5个元素宽。从现在开始,任何事情都可能发生。

在C数组中,索引是基于0的。这里的第一个元素是bhago[0]

这个

  ..., (socklen_t*)sizeof(client));

非常可怕。不要盲目抛弃编译错误。需要一个指针,代码传递一个编译时常量,在这里再次调用未定义的行为。我希望代码能够在执行此行时立即死亡。

accept()期望socklen_t *作为最后一个参数,因此传递一个:

  socklen_t socklen = sizeof client;
  ..., &socklen));