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

时间:2014-07-06 19:19:27

标签: c sockets client-server port

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

服务器端结果

./ server 5000

以下是消息:test

客户端结果

./ client localhost 5000

请输入消息:test

我收到了你的消息

请输入消息:另一个测试

请输入消息:再次测试

请输入消息:再次测试

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

server.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;
}

client.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;
}

2 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

我知道为时已晚。但对于可能有同样疑问的人,我试图回答这个问题。

<强>答案
如何将服务器程序更改为此

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.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);
        while(true)
        {   
            n = read(newsockfd,buffer,255);
            if (n < 0)
            {
                printf("ERROR reading from socket\n");
                break;
            }           
            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");
                break;
            }
        }
        close(newsockfd);
    }
    close(sockfd);
    return 0;
}  

这是改变的部分。我稍微更改了代码,以便在发生任何写入或读取错误时连接将关闭。

while ((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen)) >= 0) {
    if (newsockfd < 0) 
        printf("ERROR on accept\n");
    bzero(buffer,256);
    while(true)
    {   
        n = read(newsockfd,buffer,255);
        if (n < 0)
        {
            printf("ERROR reading from socket\n");
            break;
        }           
        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");
            break;
        }
    }
    close(newsockfd);
}