ImageVerifierCode 换一换
格式:DOC , 页数:24 ,大小:324.50KB ,
资源ID:6623643      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/6623643.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(Linux下使用套接口和GTK编写网络通信程序.doc)为本站上传会员【pc****0】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

Linux下使用套接口和GTK编写网络通信程序.doc

1、Linux下使用套接口和GTK编写网络通信程序 第一章、基础知识 1.1 套接口 1.1.1基础知识 套接口(socket)就是网络进程的ID,其可以简单的理解为网络地址(ip地址)和端口号。套接口分两种,流式套接口使用TCP协议,数据报套接口使用UDP协议。在Linux中套接口的操作类似于文件描述符,可以像操作文件一样操作他们。在Linux中使用套接口发送数据要注意字节顺序的问题,在网络传输中,是以高字节在前(big endian)的方式传送的,而本机解析这些数据,是和CPU的结构有关,在传输到网络之前,需将套接口数据结构sockaddr_in中的网络地址和端口转换为高字节在前的形式

2、 套接口的基本操作有绑定、连接、监听、应答、发送、接受、关闭等,以客户/服务器为主的网络机制其用socket进行TCP服务的简化图1-1。 一般给套接口分配的文件描述符从3开始,0为默认输入,1为默认输出,2为错误默认输出,这三个描述符固定分配给系统使用,如果将套接口文件描述符设置成相应的1/2/3,则获得的数据则输出到相应的地方。 图1-1 1.1.2 关于I/O 使用套接口主要进行数据传输,不免要与I/O打交道。其I/O操作主要有四种模型:阻塞式,非阻塞,多路复用以及信号驱动。本文的程序使用的是阻塞式的I/O,其简单但效率相对较低。阻塞在套接口应用中很重要,处理不好会导致双

3、方均处于阻塞状态,造成死锁。比如客户端进行read操作,但是对方迟迟不发送信息,导致read一直没有返回值,程序便会一直等待。 1.2 GTK GTK (Gimp Tool Kit) 为GNOME中使用的开源界面开发程序。相应的,在KDE中主要使用的是QT。GTK使用了事件触发的结构处理用户响应,其开发包包括GDK,支持包含C之内的多种编程语言 1.3 Linux下的c语言编写 这里Linux下的c语言编辑主要使用vi,编译程序使用gcc。Gcc编译过程中,有静态连接库等问题需要注意,使用的命令为 gcc -std=c99 `pkg-config --cflags --libs g

4、tk+-2.0` -lpthread client.c -o client gcc -std=c99 `pkg-config --cflags --libs gtk+-2.0` -lpthread service.c -o service 在处理字符串的时候,多应用stdlib.h和string.h里的标准库函数,区分指向常量区域的字符串指针以及字符串数组之间的区别,明确字符串数组的赋值方法(单个元素赋值或用strcat stpcpy),在Linux条件下,没有itoa函数将整型变为字符型,可以使用sprintf函数。 1.4 多线程 一个进程(process)派生另一个进程称为

5、多进程,其相比单一进程具有较高的灵活性,能够更有效地利用CPU,但是其代价为较大的内存占用以及麻烦的进程间通信,在这样的前提下产生了多线程。 多进程和多线程的区别在于,多线程中的子线程可以访问共享内存区域中的数据,简化了线程间的通信,提高了程序特别是用户界面程序的响应。但是在使用线程中要注意同时访问变量的问题,应该使用一定的机制(比如互斥锁mutex),让各个子线程以串行的方式访问并修改内存中的数据,避免出现内存使用冲突的问题。 多个线程能够共享同一个进程代码段,共有数据(用来通讯),进程打开的文件描述符,信号的处理器,进程当前目录,进程用户ID等。当然每一个线程也有其独有的东西:线程ID

6、寄存器值,堆栈,错误返回码,信号屏蔽码和优先级。 创建线程需要pthread.h头文件,连接时要使用libpthread.a的库,这里简单讲解几个和线程有关的函数。 Int pthread_create(pthread_t *tid, const pthread_attr_r *attr, void *(*func)(void*), void *arg) 四个输入参数依次为线程ID标识符,创建线程的属性,线程将要执行的函数-返回void类型指针,以及传递给函数的参数(这里,参数需是void类型的,int等类别的参数需要进行转换,多参数传递建议使用结构体)。 Int pthread_j

7、oin(pthread_t tid, void **status) 等待tid的线程终止,然后再执行下面的命令。Status指针内将保存线程的返回值。 pthread_t pthread_self(void) 返回线程ID。 pthread_cancel结束其他它由同一个进程产生的线程,这里注意,当子线程阻塞在I/O时(比如,read等待),是不可以用这个函数退出次线程的,这时就要考虑使用非阻塞的I/O获得较高的控制权和灵活性。 pthread_exit结束线程本身。 在使用Pthread时避免线程的资源在线程结束时不能得到正确释放,从而避免产生潜在的内存泄漏问题,在对待线程结束时

8、要确保该线程处于detached状态(pthread_detach()),否着就需要调用 pthread_join()函数来对其进行资源回收。 线程可以通过自身执行结束来结束,也可以通过调用pthread_exit()来结束线程的执行。另外,线程甲可以被线程乙被动结束,通过调用pthread_cancel()来达到目的,cancel并不等待线程终止, 它仅仅是提出请求。可以用如下两个函数设置本线程的应答属性。 int pthread_setcancelstate(int state, int *oldstate) state 取值可以是PTHREAD_CNACEL_ENABLE,这个值

9、允许线程接收取消请求。 int pthread_setcanceltype(int type, int *oldtype) 设置取消的类型,type取值可以是PTHREAD_CANCEL_ASYNCHRONOUS,它将使得线程在接收到取消请求后立即处理。 在默认的情况下,线程启动时的取消状态为PTHREAD_CNACEL_ENABLE,取消类型为PTHREAD_CANCEL_DEFERRED。 1.5 IP地址和端口 在笔者处的教育网段,每台电脑几乎都可以分配一个独立的IP地址,每一个学校的IP地址是在一段地址之间。 一般一台主机只有一个IP地址,除非有多块网卡。 IP地址分为内

10、网地址和外网地址,内网地址用于局域网广播,多是C网。 在网络上唯一确定一个传输数据的地址,需要IP地址和端口的支持。在这里的通信程序中,服务器使用固定的IP和端口,客户端使用自己本机的IP和随机分配的端口进行访问。为避免冲突,一般端口设置在1024之上较为合理。 在Linux下运行ifconfig可以得到本机的以太网卡IP和本机IP。无论系统是否接入网络,本机网络这个设备总是存在的,除非你在内核编译的时候禁止了网络支持,这是一个称为回送设备的特殊设备,它自动由Linux 配置以提供网络的自身连接。IP地址127.0.0.1是一个特殊的回送地址(即默认的本机地址),您可以在自己的系统上用te

11、lnet对IP地址127.0.0.1进行测试。如果有inetd进程在运行的话您会从自己的机器上获得登录提示符。Linux 可以利用这个特征在进程与仿真网络之间进行通信。 1.6 TCP&UDP TCP为面向连接的协议,其保证数据能够准确且按顺序地到达,在Socket连接选择类型为SOCK_STREAM时即使用此协议。由于其是面向连接的,通信时需要listen-connect的三步握手协议。在发送数据时,先将数据保存在缓冲区,等待对方对发送的数据进行确认后才清楚缓冲区中的数据。其实现为数据流类型的服务,需要应用程序控制数据的边界。 UDP为面向无连接的协议,其保证数据的及时性,但对消息的尺

12、寸加以限制,且没有对准确性的保证,在Socket连接选择类型为SOCK_DGRAM时即使用此协议。其通信时不需要握手协议,发送数据时直接将数据从应用缓冲区复制到系统缓冲区中,然后子程序返回。数据包的生成由UDP协议实现。其缓冲区具有一定大小,为UDP数据报的最大长度。其实现的是数据报类型服务,采用面向记录的协议。 二者比较来看,UDP服务器通常是以循环方式对多个客户进行服务的,TCP通常使用轮询或其他多线程的方式服务多个客户。 第二章、基本实现原理 2.1 基本实现结构 基本的实现结构如图2-1所示,在发送登录,刷新信息时,使用互斥锁的多线程,保证当前信息的准确性,如图B;在发送消息的

13、时候,使用直接转发的方式,如图A。但这样会有一个问题,当用户数量较多时,发送的登录和刷新信息会造成其他用户的白白等待,如图C所示。程序内部流程框图如图2-2 图2-1 图2-2 2.2 更多的想法 一个改进该问题的想法如下图所示,使用两个服务器,一个作为登录使用,另一个专门作为通信交换使用,两个服务器之间进行同步。当然这种实践叫前者复杂,这里没有完成其代码。 图2-3 第三章、部分关键代码解释 3.1 服务器代码 3.1.1 关于互斥锁 以下代码首行和末行分别取得互斥锁的所有权和释放有权。其他试图对数据加锁的线程将被阻塞直到当前线程释放对该数据的锁。 pth

14、read_mutex_lock(&mutex); USER_INFO[in_unpack.send_from].stat = 0; USER_INFO[in_unpack.send_from].sd = 0; in_unpack.tag = LOGOUT_AWK; do_pack(&in_unpack,in_pack); flag += write(new_sd[in_sd],in_pack,sizeof(in_pack)); sleep(0.1); pthread_mutex_unlock(&mutex); 3.1.2 关于线程的参数传递 pthread_create(

15、THREAD[tmp_index],NULL,do_service,(void*)flag_find); 将int格式的flag_find变为void格式的指针传递给函数do_service。 3.1.3 关于数据结构 struct msg_pack{ //message pack struct int tag; //msg type char size:2 int send_from; //msg send from char size:8 int send_to; /

16、/msg send to char size:8 char key[64]; //key used for login char size:8 char msg[PACK_MSG];//msg content char size:998 }; 定义了一个包含五个元素的结构体用于write和read时的数据结构。 3.2 用户代码 3.2.1 关于显示文本框内容的添加 gtk_text_buffer_get_end_iter(text_buffer,&iter); gtk_text_buffer_insert(t

17、ext_buffer,&iter,"this is it",-1); 3.2.2防止缓存溢出 每次在进行对数组的赋值时,检查是否出现溢出,消除潜在的core错误。 char format_cash[9]; format_char(send_to,format_cash,8); int tmp_send_from = atoi(format_cash); 从文本框中读入数据 char *login_ip = gtk_entry_get_text(GTK_ENTRY(message_entry_ip)); 第四章、运行调试结果 编译service.c和client.c两个主文

18、件,出现若干个警告,编译通过,调试基本成功。BUG报告:当服务器先于客户端关闭时会导致客户端的异常退出。程序运行截图如下。 图4-1 参考文献 宋国伟,《GTK+2.0编程范例》 张威,《Linux网络编程教程》 Warren W. Gay,《实战Linux Socket编程》 附录 define.h源代码 #include #include #include #include #include #include #include<

19、sys/select.h> #include #include #include #include #include #define MAXUSER 4 #define BUFSIZE 100 #define MYPORT 3490 #define BACKLOG 10 #define NO 0 #define LOGIN 1 #define LOGIN_AWK 2 #define LOGIN_NEG

20、3 #define REFRESH 4 #define REFRESH_AWK 5 #define REFRESH_NEG 6 #define LOGOUT 7 #define LOGOUT_AWK 8 #define LOGOUT_NEG 9 #define SEND 10 #define PACK 1024 #define PACK_HEAD 26 #define PACK_MSG 998 struct user_info{ //user info struct int sd;

21、 //socket id int stat; //on line? int id; //user id char key[12]; //user key char time[128];//user last login time }; struct user_info USER_INFO[MAXUSER] = { {-1,0,0,"0",""}, {-1,0,1,"11111111",""}, {-1,0,2,"2",""}, {-1,0,3,"3",""}, }; struct msg_pack{ /

22、/message pack struct int tag; //msg type char size:2 int send_from; //msg send from char size:8 int send_to; //msg send to char size:8 char key[64]; //key used for login char size:8 char msg[PACK_MSG];//msg content char size:998 }; pthread_m

23、utex_t mutex = PTHREAD_MUTEX_INITIALIZER; int new_sd[MAXUSER]; int tmp_index = -1; int total_online = 0; /* //build socket,init,and bind it to a port int build_ear(int ip){ //build socket int sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd < 0){ printf("cannot build socket\n")

24、 return -1; }; struct sockaddr_in my_addr; struct sockaddr_in their_addr; //init my_addr.sin_family = AF_INET; my_addr.sin_port = htons(MYPORT); my_addr.sin_addr.s_addr = htonl(ip); bzero(&(my_addr.sin_zero),8); //bind int ret = bind(sockfd,(struct sockaddr *)&my_addr,s

25、izeof(struct sockaddr)); if(ret < 0){ printf("cannot bind socket with port\n"); return -1; }; return 0; }; int parse_sig(char *in,char *flag,char *data){ char *p = NULL; int i = 0; p = strtok(in,SPLIT_TAG); flag = stpcpy(flag,p); p = strtok(NULL,SPLIT_TAG); data = stpcpy(dat

26、a,p); return 0; };*/ // used for pick number int cut_char_int(char *in,int *out,int beg,int out_len){ int in_len = strlen(in); char tmp[1024]; if(in_len < beg+out_len || beg < 0){ return -1; }; int i = 0; for(i=beg; i<=beg+out_len-1; i++){ *(tmp+i-beg) = *(in+i); }; *(

27、tmp+out_len) = '\0'; *out = atoi(tmp); return 0; }; // used for pick key,ignore blank int cut_char_char(char *in,char *out,int beg,int out_len){ int in_len = strlen(in); if(in_len < beg+out_len || beg < 0){ return -1; }; int i = beg; int j = 0; for(i=beg; i<=beg+out_len-1;

28、 i++){ if(*(in+i) == ' '){ continue; }; *(out+j) = *(in+i); j++; }; *(out+j) = '\0'; return 0; }; // used for pick msg int cut_char_talk(char *in,char *out){ int i = PACK_HEAD; for(; *(in+i) != '\0'; i++){ *(out+i-PACK_HEAD) = *(in+i); }; *(out+i-PACK_HEAD) =

29、 '\0'; return 0; }; // used for format char to 8 int format_char(char *in,char *out,int size){ int i = 0; int con = 0; for(; *(in+i) != '\0' && i

30、 *out){ int flag = sprintf(out,"%02d%08d%08d%08s%s",in->tag,in->send_from,in->send_to,in->key,in->msg); return flag; }; // unpack data struct int do_unpack(char *in,struct msg_pack *out){ int len = strlen(in); if(len < PACK_HEAD){ return -1; }; int flag_cut = 0; flag_cut

31、 cut_char_int(in,&out->tag,0,2); flag_cut += cut_char_int(in,&out->send_from,2,8); flag_cut += cut_char_int(in,&out->send_to,10,8); flag_cut += cut_char_char(in,out->key,18,8); flag_cut += cut_char_talk(in,out->msg); if(flag_cut != 0){ return -1; }; return 0; }; // do servic

32、e in thread void *do_service(void* args){ int in_sd = (int) args; char in[PACK]; // g_printf("in thread %d\n",new_sd[in_sd]); // total_online++; struct msg_pack in_unpack ; while(read(new_sd[in_sd],in,PACK) > 0){ do_unpack(in,&in_unpack); g_printf("\tread msg %s\n",in);

33、 int flag = 0; char in_pack[PACK]; switch(in_unpack.tag){ case LOGIN:{ g_printf("\tlogin\n"); pthread_mutex_lock(&mutex); if(in_unpack.send_from < 0 || in_unpack.send_from >= MAXUSER){ in_unpack.tag = LOGIN_NEG; stpcpy(in_unpack.msg,"w

34、rong user id"); }else if(strcmp(USER_INFO[in_unpack.send_from].key,in_unpack.key) != 0){ in_unpack.tag = LOGIN_NEG; stpcpy(in_unpack.msg,"wrong user key"); }else if(USER_INFO[in_unpack.send_from].stat != 0){ in_unpack.tag = LOGIN_NEG; s

35、tpcpy(in_unpack.msg,"user already login"); }else{ in_unpack.tag = LOGIN_AWK; USER_INFO[in_unpack.send_from].stat = 1; USER_INFO[in_unpack.send_from].sd = new_sd[in_sd]; }; do_pack(&in_unpack,in_pack); flag += write(new_sd[in_

36、sd],in_pack,sizeof(in_pack)); pthread_mutex_unlock(&mutex); };break; case LOGOUT:{ pthread_mutex_lock(&mutex); USER_INFO[in_unpack.send_from].stat = 0; USER_INFO[in_unpack.send_from].sd = 0; in_unpack.tag = LOGOUT_AWK; do_pack(&in_unpa

37、ck,in_pack); flag += write(new_sd[in_sd],in_pack,sizeof(in_pack)); sleep(0.1); pthread_mutex_unlock(&mutex); };break; case REFRESH:{ g_printf("\trefresh\n"); pthread_mutex_lock(&mutex); for(int i=0; i

38、FO[i].stat == 1){ char tmp_id[12]; sprintf(tmp_id,"%d",USER_INFO[i].id); strcat(in_unpack.msg,tmp_id); strcat(in_unpack.msg,"\n"); }; }; in_unpack.tag = REFRESH_AWK; do_pack(&in_unpack,in_pack); flag += write(n

39、ew_sd[in_sd],in_pack,sizeof(in_pack)); sleep(0.1); pthread_mutex_unlock(&mutex); };break; case SEND:{ g_printf("\tsend\n"); if(in_unpack.send_to < 0 || in_unpack.send_to >= MAXUSER){ g_print("\tsend to wrong user\n"); }else if(USE

40、R_INFO[in_unpack.send_to].stat != 1){ }else{ do_pack(&in_unpack,in_pack); flag += write(USER_INFO[in_unpack.send_to].sd,in_pack,sizeof(in_pack)); }; };break; }; if(flag < 0){ g_print("loop wrong flag %d\n",flag); break; }; }

41、 g_printf("\tend of this client\n"); total_online--; new_sd[in_sd] = -1; USER_INFO[in_unpack.send_from].stat = 0; close(new_sd[in_sd]); }; service.c源代码 #include #include #include #include #include #include #i

42、nclude #include #include #include #include"define.h" pthread_t THREAD[MAXUSER]; int main(int argc, char *argv[]){ gint sd; gchar buf[1024]; struct sockaddr_in *sin; gint slen; for(int i=0; i

43、 = socket(AF_INET,SOCK_STREAM,0); if(sd < 0) { g_print("cannot creat socket\n"); return -1; }; sin = g_new(struct sockaddr_in,1); sin->sin_family = AF_INET; sin->sin_port = htons(MYPORT); sin->sin_addr.s_addr = INADDR_ANY; slen = siz

44、eof(struct sockaddr_in); if(bind(sd,(struct sockaddr *)sin,slen)<0){ g_print("cannot bind\n"); return -1; }; while(1){ if(listen(sd,8)<0){ g_print("cannot listen\n"); }; int flag_accept = -1; int flag_find = -1; flag_accept = accept(sd,(struct sockaddr*)s

45、in,&slen); if(flag_accept < 0){ continue; }; for(int i=0; i

46、close(flag_accept); }else{ total_online++; g_printf("new thread create id %d\n totoal %d user on line\n",new_sd[flag_find],total_online); pthread_create(&THREAD[tmp_index],NULL,do_service,(void*)flag_find); }; }; g_print("end all\n"); // close(sd); // g_free(sin); }; c

47、lient.c源代码 #include #include #include #include #include #include #include"define.h" // global gint sd; int user_id; int refresh_flag = 0; pthread_t GETMSG; static GtkWidget *id_entry; static GtkWidget *

48、key_entry; static GtkWidget *send_button, *refresh_button, *login_button; static GtkWidget *login_window; static GtkWidget *message_entry_ip, *message_entry_id, *message_entry_key; static GtkWidget *message_entry_to, *message_entry_msg; static GtkWidget *text; static GtkTextBuffer *text_

49、buffer; static GtkTextIter iter; struct sockaddr_in service_addr; void on_delete_main_win(){ gtk_main_quit(); }; void on_delete_login_win(){ gtk_widget_set_sensitive(login_button,TRUE); gtk_widget_destroy(login_window); }; void on_open_login_win(); void on_send_msg_but(); vo

50、id on_send_refresh_but(); void on_send_login_but(); void *get_msg(); int main(int argc,char* argv[]){ GtkWidget *window; GtkWidget *vbox, *hbox; GtkWidget *view; GtkWidget *label_1, *label_2; // main window gtk_init(&argc,&argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服