c - 服务器未向客户端返回最后一条响应消息

标签 c sockets

我制作了一个客户端/服务器程序,其中来自客户端服务器的每个命令都返回“Hello,来自服务器”,退出时应返回“退出服务器”,但它返回“Hello,来自服务器”并退出

我尝试在break语句之前放置一个字符串,并在while循环之后放置一个字符串,两者都会打印,而从服务器结束时不会打印到客户端

客户端.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>

int main(void)
{
    int client_socket = socket(AF_INET, SOCK_STREAM, 0); //creating client socket

    struct sockaddr_in server_address;  //creating structure for server address
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    if(connect(client_socket,(struct sockaddr *)&server_address,sizeof(server_address))<0)  //establishing connection between client and server
    {
        printf("Something went wrong while connecting to server!\n");
        close(client_socket);
        return -3;
    }

    char server_response[256];  //creating buffer for receiving data from server
    char client_request[256];   // creating buffer for sending request from the client
    while(1)
    {
        printf("Enter command: ");
        scanf("%s",client_request);
        send(client_socket,&client_request,sizeof(char)*strlen(client_request),0); // sending command from the client
        memset(server_response,0,sizeof(server_response)); // cleaning the buffer
        recv(client_socket,&server_response,sizeof(server_response),0); //data receiving from the server
        printf("%s\n",server_response); //printing data to console
        if(strcmp(client_request,"exit")==0)break; // termnating condition for the client
    }
    close(client_socket);   //closing the socket
    return 0;
}

服务器.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>

void print_client(struct sockaddr_in client_address)
{
    unsigned long address = ntohl(client_address.sin_addr.s_addr);
    unsigned int a = (address & (0xff));
    unsigned int b = (address & (0xff <<  8)) >>  8;
    unsigned int c = (address & (0xff << 16)) >> 16;
    unsigned int d = (address & (0xff << 24)) >> 24;
    printf("Cient address: %u.%u.%u.%u ",d,c,b,a);
    return;
}

int main(void)
{
    char server_msg[256] = "Hello, From server";    // server response message
    char end_msg[256] = "Exiting the server";// server ending message
    char client_request[256];
    int client_request_len;
    int server_socket = socket(AF_INET, SOCK_STREAM, 0); // creating tcp/ip socket for server

    struct sockaddr_in server_address;  // creating server address
    server_address.sin_family = AF_INET;    
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    if(bind(server_socket,(struct sockaddr *)&server_address, sizeof(server_address)) < 0) //binding socket to server address
    {
        printf("Could not bind address try later!\n");
    }
    listen(server_socket, 5); //making connection limited to 5 clients
    struct sockaddr_in client_address;
    unsigned int client_address_len;
    int client_socket = accept(server_socket,(struct sockaddr *)&client_address,&client_address_len);   //accepting the client request
    print_client(client_address);
    printf(" and port: %u connected\n",client_address.sin_port);
    send(client_socket,server_msg,sizeof(server_msg),0);
    while(1)
    {
        memset(client_request,0,sizeof(client_request)); // cleaning the buffer
        recv(client_socket,&client_request,sizeof(client_request),0); // receiving request from client
        printf("Message from client: %s\n",client_request);
        if(strcmp(client_request,"exit")==0)
        {
            printf("breaking condition\n");
            break; // terminating the connection
        }
        send(client_socket,server_msg,sizeof(server_msg),0);    // sending server_msg to client
    }
    printf("send this message\n");
    send(client_socket,end_msg,sizeof(end_msg),0);
    close(server_socket); // closing the server socket
    return 0;   
}

实际结果 “客户端”输入命令:shubham 你好,来自服务器 输入命令:库马尔 你好,来自服务器 输入命令:结束 你好,来自服务器 输入命令:退出 您好,来自服务器 预期结果“客户端”

Hello, From server
Enter command: kumar
Hello, From server
Enter command: end
Hello, From server
Enter command: exit
Exiting the server

实际结果“服务器”

Cient address: 127.0.0.1  and port: 20710 connected
Message from client: shubham
Message from client: kumar
Message from client: end
Message from client: exit
breaking condition
send this message

最佳答案

这是因为您在接受客户端连接后已经发送了 Hello, From server,因此事件的顺序如下所示:

  1. 客户端:连接并等待用户输入
  2. 服务器:接受连接,发送服务器消息S(来自服务器的问候)
  3. 用户:输入命令C(随便)
  4. 客户端:发送C,从步骤2读取S,等待用户输入
  5. 服务器:读取C,发送S
  6. 用户:输入命令退出
  7. 客户端:发送Exit,读取第5步中的S,退出
  8. 服务器:读取退出,发送E(从服务器退出),但此时客户端可能不再连接。

如果您在接受连接之后但在 while 循环之前删除消息的发送,那么它应该按预期工作。

关于c - 服务器未向客户端返回最后一条响应消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57773028/

相关文章:

c - 如何在 Hangman 游戏 C 中使用数组

c - 使用两个源文件编译内核模块时出错

c - 是否有 fsync 但带有路径参数

sprintf() 的输入和输出字符串可以相同吗?

c - c中的静态变量

java - java中通过Socket进行文件传输

c++ - msgpack 打包结构

mysql - 在个人项目中使用mysql NPM模块时出现ER_ACCESS_DENIED_ERROR

c++ - 在同一个 io_service 对象上 boost 异步套接字和线程池

c# - ZeroMQ线程/任务建议