c - 在无限循环中通过套接字进行客户端服务器通信

标签 c sockets client-server port

我在下面有一个客户端页面和一个服务器页面的代码,我想为此从客户端向服务器端发送五条消息(无论如何,对于这个初始测试)。如果我不把它放在一个循环中,代码就可以正常工作,但是我只能在客户端和服务器关闭之前发送一条消息。当我将代码放入循环中时,它似乎陷入了某种僵局。我得到的结果在下面,后面是代码。我尝试了各种更改并进行了广泛的研究,但就是无法使其发挥作用。预先感谢您提供的任何解决方案。

服务器端结果

./服务器 5000

这是消息:测试

客户端结果

./client localhost 5000

请输入留言:test

我收到你的信息了

请输入消息:另一个测试

请输入消息:再次测试

请输入信息:再次测试

//服务器停止确认收到消息,我必须不断重置客户端和服务器

服务器.c

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

int main(int argc, char *argv[])
{
    int sockfd, newsockfd, portno, clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    int n;
    if (argc < 2) {
        printf("Need at least two arguments\n");
        exit(1);
    }
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) 
        printf("ERROR opening socket\n");
    bzero((char *) &serv_addr, sizeof(serv_addr));
    portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
    if (bind(sockfd, (struct sockaddr *) &serv_addr,
         sizeof(serv_addr)) < 0) 
    printf("ERROR on binding\n");
    listen(sockfd,atoi(argv[1]));
    clilen = sizeof(cli_addr);
    while ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) >= 0) {
        if (newsockfd < 0) 
            printf("ERROR on accept\n");
        bzero(buffer,256);
        n = read(newsockfd,buffer,255);
        if (n < 0) printf("ERROR reading from socket\n");
        printf("Here is the message: %s\n",buffer);
        n = write(newsockfd,"I got your message\n",18);
        if (n < 0) printf("ERROR writing to socket\ns");
    }
    close(sockfd);
    return 0;
}

客户端.c

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

int main(int argc, char *argv[]) {
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    char buffer[256];
    if (argc < 3) {
        printf("Not enough arguments\n");
        exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        printf("Error opening socket\n");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        printf("Error: no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
          (char *)&serv_addr.sin_addr.s_addr,
          server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
        printf("Error connecting\n");
    int i = 0;
    while (i < 5) {
        printf("Please enter the message: ");
        bzero(buffer, 256);
        fgets(buffer, 255, stdin);
        n = write(sockfd, buffer, strlen(buffer));
        if (n < 0)
            printf("Error writing to socket");
        bzero(buffer, 256);
        n = read(sockfd, buffer, 255);
        if (n < 0)
            printf("Error reading from socket");
        printf("%s\n", buffer);
        i++;
    }
    close(sockfd);
    return 0;
}

最佳答案

在接受另一个连接之前,您需要重组代码以处理您拥有的一个连接。这是糟糕的代码,但却是你想做的事情的基本模板。即使这样,您也不能一次处理多个连接。您必须多路复用或线程。此外,始终在循环中读/写,因为您不能保证在任何一次调用中都能获得完整的请求。了解并使用perror还是兄弟。

void do_stuff(int sock)
{
    for (int i = 0; i < 5; ++i)
    {

        bzero(buffer, 256);

        n = read(newsockfd, buffer, 255);

        if (n < 0)
            printf("ERROR reading from socket\n");

        printf("Here is the message: %s\n", buffer);

        n = write(newsockfd, "I got your message\n", 18);

        if (n < 0)
            printf("ERROR writing to socket\ns");
    }
}


while ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) >= 0)
{
    if (newsockfd < 0)
        printf("ERROR on accept\n");

    do_stuff(newsockfd);

    close(newsockfd);
}

关于c - 在无限循环中通过套接字进行客户端服务器通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24599458/

相关文章:

c - 创建服务器/客户端 TCP/IP 程序时遇到问题

java - 我如何使用java中的客户端服务器套接字编程通过网络流式传输 Parquet 文件

java - 为 C++ 服务器实现 Java TCP 客户端

c - 静态库和动态库有什么区别

python - 将 scikit-learn ML 模型转换为用于微 Controller 的 C 语言

c - 我必须从 C 文本文件中读取键的值

c - 在 C 中,我如何访问/迭代动态添加到 fd_set 的文件描述符?

node.js - 为什么在静态连接时Web套接字的延迟会有所不同?

带套接字的 Java 客户端和 PHP 服务器

node.js - 使用分离的客户端和服务器进行身份验证