我正在使用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上正常工作。
感谢任何有贡献的人!
答案 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的主线程),实际上该主线程也很好地集成到了主循环中。参见例如: