聊天程序的信息接收问题

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

我正在用C语言编写一个聊天程序,使用c socket编程和gtk+作为GUI.我有两个程序的变体,分别运行在两台计算机上,一个变体有客户端的代码,另一个有服务器端的代码,两者都有相同的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");
                }
        }
}

我很想得到一些帮助,因为我不知道为什么它不能工作, 接收和发送功能都能在对方的图形用户界面上正常工作。

谢谢大家的贡献!

c sockets gtk glade gtk#
1个回答
0
投票

你真的不应该试图把你自己的手卷的 while (TRUE) 循环,而不是GTK正在使用的事件循环(也就是GMainLoop),通过调用 gtk_main_iteration(). 还请注意,文档中甚至明确提到这是一个阻塞调用。

如果没有事件等待处理,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 (如果你真的想走低级路线,整合一个自定义的主循环,但对于你的用例来说,这似乎是矫枉过正)
© www.soinside.com 2019 - 2024. All rights reserved.