麻烦在C和Linux套接字连接 [英] Trouble with socket connection in C and Linux

查看:158
本文介绍了麻烦在C和Linux套接字连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个简单的项目,因为我想了解更多关于Linux下的socket编程。我创建了一个非常简单的服务器,将接受连接,并用一个语句回应。不过,我添加了一个while循环来保持连接活着,所以我可以保持没有它断开发送命令。然而,有一次,我发的第一个命令,该服务器将连接回应。第一个响应后,它只是处于闲置状态,并退出响应。正如你可以从code诉说,我试过接受系统调用内部和外部while循环,因为我不知道,如果调用accept不止一次在同一客户端上会导致它挂起。有一次,我感动了while循环外的接受呼叫,功能仍然挂起,所以我不知道在哪里从这里走。

 的#includeserver.h
#包括LT&; netinet / in.h中>
#包括LT&; SYS / socket.h中>
#包括LT&;&stdlib.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&string.h中GT;结构服务器{
    INT的sockfd;
    INT client_socket; //使用的插座,用于与所述客户端
    INT积压; //最大挂起的连接
    结构SOCKADDR_IN * serv_addr;
    结构SOCKADDR_IN * client_addr; //客户信息时,它连接
};INT server_init(服务器** SERV,诠释了max_connections)
{
    * SERV =(服务器*)malloc的(的sizeof(服务器));
    如果(* SERV){
        (* SERV) - GT;积压= max_connections的;
        (* SERV) - GT;的sockfd =插座(AF_INET,SOCK_STREAM,IPPROTO_TCP);        (* SERV) - GT; serv_addr =(结构SOCKADDR_IN *)malloc的(的sizeof(结构SOCKADDR_IN));
        如果((* SERV) - GT; serv_addr)
            memset的((* SERV) - GT; serv_addr->的sin_zero,0,sizeof的((* SERV) - GT; serv_addr->的sin_zero));
        其他{
            免费(* SERV);
            返回-1;
        }        (* SERV) - GT; serv_addr-> sin_family = AF_INET;
        (* SERV) - GT; serv_addr-> sin_addr.s_addr = INADDR_ANY;    }其他{
        返回-1;
    }    返回0;
}/ *
 *绑定服务器的端口并开始听
 * /
INT server_bind(服务器* SERV,诠释端口)
{
    INT结果为0;    serv-> serv_addr-> sin_port = htons(端口);
    如果(绑定(serv->的sockfd,(结构sockaddr *)&serv- GT; serv_addr,(socklen_t的)的sizeof(*(serv-> serv_addr)))小于0)
        返回-1; //如果绑定调用失败,我不想继续尝试监听电话    如果(听(serv->的sockfd,serv->积压)℃下)
        结果= -1;    返回结果;
}INT server_unbind(服务器* SERV)
{
    INT结果为0;    如果(接近(serv-> client_socket)℃的)
        结果= -1;    如果(接近(serv->的sockfd)℃的)
        结果= -1;    返回结果;
}诠释server_accept_connections(服务器* SERV,INT(* process_data)(字符*缓冲区,ssize_t供长度,INT client_scoket))
{
    INT结果为0;
    字符*缓冲=(字符*)malloc的(的sizeof(char)的* 250);    如果(缓冲液){
        INT长度= sizeof的((SERV) - GT; client_addr); //可以做一些与此有关的每一次计算它保持
        serv-> client_socket =接受(serv->的sockfd,(结构sockaddr *)(SERV) - GT; client_addr,&安培;长度);        而(结果== 0){
            // INT长度= sizeof的((SERV) - GT; client_addr);
            // serv-> client_socket =接受(serv->的sockfd,(结构sockaddr *)(SERV) - GT; client_addr,&安培;长度);
            ssiz​​e_t供数据长度=的recv(serv-> client_socket,缓冲器,的sizeof(缓冲液),0);
            结果=(* process_data)(缓冲,数据长度,serv-> client_socket);
        }
        结果= 0;
    }
    其他
        结果= -1;    免费(缓冲);
    返回结果;
}无效server_destroy(服务器* SERV)
{
    如果(SERV){
        免费(serv-> serv_addr);
        免费(SERV);
    }
}


 的#include<&stdio.h中GT;
#包括server.h
#包括LT&;&string.h中GT;
#包括LT&;&stdlib.h中GT;INT process_netdata(字符*缓冲区,ssize_t供长度,INT socket_desc)
{
    的printf(%S,缓冲区);
    如果(STRCMP(缓冲,跳槽)!= 0){
        字符*海峡=我收到你的信息;
        INT str_length = strlen的(STR);
        写(socket_desc,STR,str_length);
        返回0;
    }
    其他{
        字符*海峡=跳槽获得了;
        INT str_length = strlen的(STR);
        写(socket_desc,STR,str_length);
        返回-1;
    }
}INT主(INT ARGC,字符** argv的)
{
    服务器*服务器;
    int值= 0;    值= server_init(安培;服务器,10);
    的printf(server_init:%I \\ N,值);    值= server_bind(服务器,2021);
    的printf(server_bind:%I \\ N,值);    值= server_accept_connections(服务器,和放大器; process_netdata);
    的printf(server_accept:%I \\ N,值);    值= server_unbind(服务器);
    的printf(server_unbind:%I \\ N,值);    值= server_destroy(服务器);
    的printf(server_destroy:%I \\ N,值);    返回0;
}


解决方案

您丢失到餐桌,使家长继续听(接受)新的连接,而孩子建立的连接上运行。

I am working on a simple project because I wanted to learn more about socket programming under Linux. I created a very simple server that will accept connections and respond with a single statement. However, I added a while loop to keep the connection alive, so I could keep sending commands without it disconnecting. However, Once I send the first command, the server will respond to the connection. After the first response, it just sits idle and quits responding. As you can tell from the code, I tried the accept system call inside and outside of the while loop because I was not sure if calling accept more than once on the same client would cause it to hang. Once I moved the accept call outside of the while loop, the function still hangs, so I am not sure where to go from here.

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

struct server {
    int sockfd;
    int client_socket; //the socket used for communication with the client
    int backlog; //maximum pending connections
    struct sockaddr_in *serv_addr;
    struct sockaddr_in *client_addr; //the clients information when it connects
};

int server_init(server **serv, int max_connections)
{
    *serv = (server *)malloc(sizeof(server));
    if (*serv) {
        (*serv)->backlog = max_connections;
        (*serv)->sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

        (*serv)->serv_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in));
        if ((*serv)->serv_addr)
            memset((*serv)->serv_addr->sin_zero, 0, sizeof((*serv)->serv_addr->sin_zero));
        else {
            free(*serv);
            return -1;
        }

        (*serv)->serv_addr->sin_family = AF_INET;
        (*serv)->serv_addr->sin_addr.s_addr = INADDR_ANY;

    } else {
        return -1;
    }

    return 0;
}

/*
 * Bind the server to a port and start listening
 */
int server_bind(server *serv, int port)
{
    int result = 0;

    serv->serv_addr->sin_port = htons(port);
    if (bind(serv->sockfd, (struct sockaddr *)serv->serv_addr, (socklen_t)sizeof(*(serv->serv_addr))) < 0)
        return -1; //if the bind call fails, I dont want to continue to try the listen call

    if (listen(serv->sockfd, serv->backlog) < 0)
        result = -1;

    return result;  
}

int server_unbind(server *serv)
{
    int result = 0;

    if (close(serv->client_socket) < 0)
        result = -1;

    if (close(serv->sockfd) < 0)
        result = -1;

    return result;
}

int server_accept_connections(server *serv, int (*process_data)(char *buffer, ssize_t length, int client_scoket))
{
    int result = 0;
    char *buffer = (char *) malloc(sizeof(char) * 250);

    if (buffer) {
        int length = sizeof((serv)->client_addr); //may do something with this to keep from calculating it every time
        serv->client_socket = accept(serv->sockfd, (struct sockaddr *)(serv)->client_addr, &length);

        while (result == 0) {
            //int length = sizeof((serv)->client_addr);
            //serv->client_socket = accept(serv->sockfd, (struct sockaddr *)(serv)->client_addr, &length);
            ssize_t data_length = recv(serv->client_socket, buffer, sizeof(buffer), 0);
            result = (* process_data)(buffer, data_length, serv->client_socket);
        }
        result = 0;
    }
    else
        result = -1;

    free(buffer);
    return result;
}

void server_destroy(server *serv)
{
    if (serv) {
        free(serv->serv_addr);
        free(serv);
    }
}


#include <stdio.h>
#include "server.h"
#include <string.h>
#include <stdlib.h>

int process_netdata(char *buffer, ssize_t length, int socket_desc)
{   
    printf("%s",buffer);
    if(strcmp(buffer, "quit") != 0) {
        char *str = "I got your message";
        int str_length = strlen(str);
        write(socket_desc, str, str_length);
        return 0;
    }
    else {
        char *str = "quit received";
        int str_length = strlen(str);
        write(socket_desc, str, str_length);
        return -1;
    }
}

int main(int argc, char **argv)
{
    server *server;
    int value = 0;

    value = server_init(&server, 10);
    printf("server_init: %i\n", value);

    value = server_bind(server, 2021);
    printf("server_bind: %i\n", value);

    value = server_accept_connections(server, &process_netdata);
    printf("server_accept: %i\n", value);

    value = server_unbind(server);
    printf("server_unbind: %i\n", value);

    value = server_destroy(server);
    printf("server_destroy: %i\n", value);

    return 0;
}

解决方案

You are missing to fork so that the parent continues to listen(accept) for new connections , while the child operates on the established connection.

这篇关于麻烦在C和Linux套接字连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆