服务器和客户端的聊天程序,C 语言的套接字编程

问题描述 投票:0回答:1

我打算使用 client.c 和 server.c 的套接字编写一个简单的聊天程序 这是我收到的要求:

服务器:

  • 接受一个连接
  • 通过先接受消息然后发送用户输入的消息来与客户端聊天。
  • 如果客户端消息是“结束”,服务器将关闭连接。
  • 否则,就永远继续交换消息。 客户:
  • 连接到服务器
  • 通过将用户输入字符串发送到服务器来开始聊天,然后向用户显示服务器响应。
  • 如果用户输入“end”,客户端会将其发送到服务器并终止连接。

这是我为 server.c 编写的代码:

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

int main(){

    unsigned short port;
    struct sockaddr_in Client_info;
    socklen_t Client_Info_Len;

    struct sockaddr_in Server_info;
    int Socket_Serv_FD, Socket_Client_FD;
    int result;

    char message[100];
    char Message_From_Client[100];

    port = 23232;

    printf("Server initiating connection ... \n");

    // create socket
    Socket_Serv_FD = socket(AF_INET, SOCK_STREAM, 0);
    // check for failure
    if(Socket_Serv_FD < 0){
        printf("Socket creation failed.");
        return -1;
    }

    // binding information
    Server_info.sin_family = AF_INET;
    Server_info.sin_port = port;
    Server_info.sin_addr.s_addr = INADDR_ANY;


    // bind with port to the socket
    result =  bind(Socket_Serv_FD, (struct sockaddr *)&Server_info, sizeof(struct sockaddr_in));
    if(result < 0){
        printf("Binding socket failed.");
        return -1;
    }

    // listen for connections on socket
    result = listen(Socket_Serv_FD, 0);
    if(result < 0){
        printf("Listen socket failed");
        return -1;
    }

        // accept when a connection occurs
        Socket_Client_FD = accept(Socket_Serv_FD, (struct sockaddr *)&Client_info, &Client_Info_Len);
        if(Socket_Client_FD < 0){
            printf("Socket connection failed.");
            return -1;
        }

    while(1){
        // read message from client
        result = read(Socket_Client_FD, &Message_From_Client, sizeof(Message_From_Client));
        if(result < 0){
            printf("Socket failed.");
            return -1;
        }

        printf("Message from client >> %s \n", Message_From_Client);

        // close socket when user enters 'end'!
        if(strcmp(Message_From_Client, "end") == 0){
            printf("Closing connection ... \n");
            break;
        }

        // prompt for message to send to client
        printf("Type a message to the client : ");
        scanf("%[^\n]", message);
        //fgets(message, 100, stdin);

        // send message to client
        result = write(Socket_Client_FD, &message, strlen(message));
        if(result < 0){
            printf("Message failed.");
            return -1;
        }
    }
    close(Socket_Serv_FD);
    close(Socket_Client_FD);
    return 0;
}

这是我的 client.c 代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include <string.h>

int main(){

    struct sockaddr_in Server_info;
    int Socket_FD;
    int result;
    
    char message[100];
    char Message_From_Server[100];
    
    int port = 23232;
    
    printf("Initiating connection ... \n");
    
    // create a socket
    Socket_FD = socket(AF_INET, SOCK_STREAM, 0);
    if(Socket_FD == -1){
        printf("Socket creation failed.");
        return -1;
    }   
    
    // bind information
    Server_info.sin_family = AF_INET;
    Server_info.sin_port = port;
    Server_info.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    // listen for connections
    result = connect(Socket_FD, (struct sockaddr *)&Server_info, sizeof(struct sockaddr_in));
    if(result < 0){
        printf("Connect socket failed.");
        return -1;
    } 
        
    while(1){
        // get input message from user
        printf("Type a message to server or 'end' to close connection : ");
        scanf("%[^\n]", message);
        //fgets(message, 100, stdin);

        // send to server
        result = write(Socket_FD, &message, sizeof(message));
        if(result < 0){
            printf("Message failed.");
            return -1;
        }
        
        // close socket when user enters 'end'!
        if(strcmp(message, "end") == 0){
            printf("Closing connection ... ");
            close(Socket_FD);
            return 0;
        }
        
        // receive from server
        result = read(Socket_FD, &Message_From_Server, strlen(Message_From_Server));
        if(result < 0){
            printf("Message failed.");
            return -1;
        }
        
        printf("Message from server >> %s \n", Message_From_Server);
        
    }
}

当我运行该程序时,它似乎首先工作,提示客户端向服务器发送消息,然后在我按回车键后将该消息发送到服务器。但是,在我尝试从服务器将消息发送回客户端后,代码中断并在终端中输出无限循环。这意味着客户端和服务器之间会稳定地来回发送消息,直到客户端输入“结束”。

这是我收到的输出::

首先我启动程序,它会提示客户端输入消息 enter image description here 接下来我输入 msg 'hello server' 并按 Enter 键,服务器接收到 msg 正常并提示发送回 msg enter image description here 接下来我输入 msg 'hello client' 并按 Enter 键,但这是结果输出 enter image description here

提前感谢您的任何帮助(:

c sockets client-server
1个回答
0
投票

首先,不要使用 scanf 来读取您的输入。我看到您尝试(也许?)使用 fgets 但显然没有成功,因为它已被注释掉。现在您应该记住 fgets 最多读取“size”-1 个字符和换行符 ( ) 字符,因此您需要将其从字符串中删除。有不同的方法可以实现这一目标,我使用的是

message[strcspn(message, "\n")] = 0;

同时 scanf 只会解析与其格式说明符匹配的任何内容,其他所有内容都留在缓冲区中供您管理。当我尝试使用 scanf 运行代码时,我得到了一个无限循环,就像你所做的那样。 现在,我还想提一下,我没有使用 write/read,而是使用了 send/recv,当在函数调用中使用 0 标志时,它应该与 write/read 几乎相同,也许对您来说会有所不同。 即,在client.c

result = write(Socket_FD, &message, sizeof(message));

成为

result = send(Socket_FD, message, sizeof(message),0);

result = read(Socket_FD, &Message_From_Server, strlen(Message_From_Server);

成为

result = recv(Socket_FD, Message_From_Server, sizeof(Message_From_Server),0);

server.c 中的相同更改
请注意,上述更改只是允许您的程序按照最初的预期运行,您仍然需要考虑其他所有事情,因为该程序可能会以无数种方式崩溃或以非预期方式运行。希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.