接收聊天程序消息时出现问题

时间:2020-06-12 08:39:58

标签: c sockets gtk glade gtk#

我正在使用c套接字编程和gtk +作为GUI来使用C编写聊天程序。 我有2种变体,分别在2台不同的计算机上运行,​​一种变体具有客户端代码,另一种具有服务器端代码,两者都具有相同的GUI和相同的用户功能选项。

当客户端是GUI且服务器在没有GUI的情况下运行时,我的程序可以工作,但是,当我尝试为服务器启用GUI时,客户端仍可以连接到服务器,但是消息似乎没有发送通过某些原因。

我使用了Glade,这是一个可以轻松创建GUI的软件,因此语法与gtk略有不同,但是它使用的是gtk,因此应该相同。 服务器GUI的主要功能如下:

int main(int argc, char *argv[])
{
    //GtkBuilder      *builder;
    GtkWidget       *window;

    //creating a widgets from type app_widgets
    app_widgets     *widgets = g_slice_new(app_widgets);
    //GtkTextIter iter;

    //creating gtk_init
    gtk_init(&argc, &argv);
    printf("creating gtk_init successfully");

    //using gtk_builder to create the graphics for the gui using glade
    builder = gtk_builder_new_from_file("glade/window_main.glade");

    //binding the builder to the main container
    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));


    // Get pointers to widgets
    //pointer to the main text view where chat is shown
    widgets->w_txtvw_main = GTK_WIDGET(gtk_builder_get_object(builder, "txtview_main"));
    //pointer to main text buffer that displays the chat
    widgets->textbuffer_main = GTK_TEXT_BUFFER(gtk_builder_get_object(builder, "textbuffer_main"));
    //pointer to text buffer where user can type msgs for server
    widgets->textbuffer_type = GTK_TEXT_BUFFER(gtk_builder_get_object(builder, "textbuffer_type"));


    //connecting the widgets to signal to the builder
    gtk_builder_connect_signals(builder, widgets);

    //gtk_widget_show is called once done setting up widget settings
    gtk_widget_show(window);

    //start client side
    //connecting to sock
    sock = startServer();
    printf("sock: %d", sock);
    if(sock < 0) {
        printf("PROGRAM ERROR: Client did not launch!\n");
        exit(0);
    }
    int valListen = listenToSock(sock);
    printf("valListen: %d\n", valListen);
    if(valListen == -1) {
        printf("PROGRAM ERROR: Server failed listening to socket");
        printf("Please Relaunch the Application!");
        exit(0);
    }
    printf("sock: %d", sock);
/*
    //validating key generation
    int valKey = getKey(keyP);
    //once password was entered successfully, check will be changed to 1
    int check = 0;

    if(valKey < 0) {
        printf("PROGRAM ERROR: password hashed did not hash successfully");
        exit(0);
    }
*/


    //currReceive is the status of the received data, if equal to 1 than data received,
    int currReceive = 0;

    //bufOutput is the data received
    char bufOutput[] = "";
    //pointer to bufOutput
    char  * bOP = bufOutput;

    //using a while loop for gtk_main_iteration
    //using gtk_main_iteration() instead of gtk_main() because i need to receive msgs while gui works - need to handle a few events
    while (1==1) {
        //runs 1 iteration of main loop
        gtk_main_iteration();

        //checking if received data
        currReceive = receive(bOP, sock, key, valQ);

        //currReceive = 1 if data was received
        if(currReceive == 1) {
            //printing msg in cmd
            printf("\nMessage: %s<\n", bOP);

            //updating the main buffer for viewing chat with the new msg received
            update_main_viewedit(widgets, bOP, "Server: ");
        }
        //if receiving failed, quit
        if(currReceive == -1) {
            printf("PROGRAM ERROR: Receiving from server failed");
            on_window_main_destroy();
            return -1;
        }
    }


    //free widgets memory
    g_slice_free(app_widgets, widgets);

    return 0;
}

接收功能正常工作,因为我已经在GUI外部对其进行了测试,并且还运行了一个简单的功能来测试接收和发送功能,它们可以无缝运行: 简单的函数如下所示:


void communicateUsingFunctions(int sock) {


        int valid;
        char info[MAX];
        char * send = info;
        while(1 == 1) {
                valid = receive(send, sock, 3, 0);
                if(valid == 1) {
                        printf("Message From Functions: %s", send);
                        sendToClient(send, sock, "dsad");
                }
        }
}

我希望获得一些帮助,因为我不知道为什么它不起作用,因此接收和发送功能都可以在另一方的GUI上正常工作。

感谢任何有贡献的人!

1 个答案:

答案 0 :(得分:0)

您真的不应该尝试通过调用while (TRUE)来组合您自己的手动gtk_main_iteration()循环而不是GTK正在使用的事件循环(即GMainLoop)。还要注意,文档甚至明确提到这是一个阻塞调用:

如果没有等待处理的事件,GTK将阻塞,直到注意到下一个事件为止。

人们试图做这种时髦的事情,实际上就是将gtk_main*()从GTK4中删除的原因(赞成只使用GtkApplication)。所以这个:

//using gtk_main_iteration() instead of gtk_main() because i need to receive msgs while gui works - need to handle a few events

并不是必须同时运行内容的好方法。

如何实际解决此问题:有多种方法可以在GLib中调用异步代码,以免阻塞主线程(运行UI的主线程),实际上该主线程也很好地集成到了主循环中。参见例如:

  • GIOStream(及其几个​​子类)
  • GSocket
  • GSource(如果您真的想降级并集成自定义主循环,但是对于您的用例来说似乎有些过分了)