欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    linux环境下c语言书写socket服务器程序的步骤和注意事项.docx

    • 资源ID:30700395       资源大小:31.46KB        全文页数:28页
    • 资源格式: DOCX        下载积分:10金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    linux环境下c语言书写socket服务器程序的步骤和注意事项.docx

    1、linux环境下c语言书写socket服务器程序的步骤和注意事项在linux下用c语言编写socket服务器。首先分析需要解决的问题:1. Socket的处理机制。一般的处理方法是在服务端socket初始化和建立监听之后,开启一个while死循环。不断接受传递过来的socket链接请求,如果链接请求成功,开启一个子进程fork,在子进程中对socket进行处理。处理完毕之后,子进程结束退出。经本人测试研究发现了1中框架的几个问题,比较的突出。具体如下。2. 开启子进程容易产生僵尸进程。一开始的代码不完善,在子进程中exit后,父进程没有对其进行操作,导致了子进程成为僵尸进程,处理此问题有3种方

    2、法,将在后面进行详细说明。3. Socket的处理容易不严谨,导致程序奔溃。Socket的处理要严谨,否则在程序的运行过程中会出现socket资源不能释放的问题。4. 日志文件的处理。在多进程(线程)处理中会面临一个日志文件不可共享写的问题。本文中的代码均为作者测试使用过,在本文的最后会附上所有代码,如有疑问或者需要可以联系作者,qq:398810897。具体问题分析:1. socket的基本框架(代码文件为server01.c)。在windows和linux下的socket编程基本上是一样的,没有多大的差别,都是遵循着 创建socket、定义socket(socket赋值)、绑定socket

    3、、开启监听、socket收发、关闭socket的流程来的,在windows下一开始还需要初始化socket版本,在这里主要针对的linux环境下的socket,所以windows下的东西就不细说了。创建可以收发数据的socket的必须的步骤如下:/创建socket sock=socket(AF_INET,SOCK_STREAM,0); if(sock0) printf(socket errorn); return 0; printf(sock-ret=%dn,sock); /网络字节序 server.sin_family=AF_INET; server.sin_addr.s_addr=INAD

    4、DR_ANY; server.sin_port=htons(6000);/.MYPORT bzero(&(server.sin_zero),8); setsockopt(sock,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(int); /bind if(ret=bind(sock,(struct sockaddr *)&server,sizeof(struct sockaddr)0)/*bind() printf(bind errorn); return 0; printf(bind-ret=%dn,ret); ret=-9

    5、; if(ret=listen(sock,100)0)/*listen() printf(listen errorn); return 0; printf(listen-ret=%dn,ret);在socket的创建以及初始化之后,做一个while(1)的死循环进行和客户端的链接。while(1) namelen=sizeof(struct sockaddr_in);/sockaddr_in:地址信息 if(msgsock=accept(sock,(struct sockaddr *)&client,&namelen)=(n=recv(sockettemp,data_buf,MAXLINE,0

    6、) continue; else send(sockettemp,ch_send_back,strlen(ch_send_back),0); close(sockettemp); break; close(sockettemp); printf(SOCKET END =n); exit(0); 以上就是一个简单的socket服务器程序的框架了。2. 僵尸进程的处理。在程序运行之后,会出现如下的问题,就是fork了子进程之后,父进程便不再处理子进程,导致了僵尸进程的出现。如下图所示,会出现一个server01 的僵尸进程:为了避免这个问题的出现,现有四种方式可以处理。(1) 父进程通过wait和

    7、waitpid等函数等待子进程结束,这会导致父进程挂起。执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。(2) 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。(3) 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核

    8、会回收,并不再给父进程发送信号(4)fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。 具体的测试结果:(1) 方法是可以避免僵尸进程的产生,但是效率很低,每一次fork了子进程,父进程都要等到子进程exit了才能继续运行,不适合在并发量很高的服务器程序上使用。(2) 在程序中定义一个signal的函数void proc_child(int SIGNO);然后在server监听了之后,和客户端链接之前,调用此函数signal(SIGCHLD, proc_child);函数的具

    9、体实现如下:void proc_child(int SIGNO) int pid = -1; int stat; pid = waitpid(-1, &stat, WNOHANG);具体代码参考server02.c。试验结果还是比较满意,在单客户端访问时,效率几乎没什么影响,也不会产生僵尸进程,但是多个客户端,或者长期大量的链接的时候还是会产生僵尸进程。测试环境比较难以搭建。(3) 方法可以,而且简单容易实现,具体代码参考server03.c。(4) 没有测试,所以这里就只好不说了。3. 在测试的过程中发现了由于作者一开始对socket没有释放导致程序不能收发数据的现象。主要是在accept之

    10、后,跳出了fork之后没有close造成的。4. 日志文件是一个比较麻烦的问题。一般情况下,日志要写到一起,只能一个一个的进程对文件进行操作,必然影响程序的并发性。这种情况下就需要建立一个缓冲区,将日志的数据保存到缓冲区中,然后在定时刷新,将缓冲区中的数据写到日志里面去。在windows下,作者比较喜欢使用一个动态链接库建立缓冲区的方法来实现,而在linux下,作者使用了一个比较简单的pipe(管道)的方法来实现这个。、具体的代码见server04.附录-代码Server01:/*/#include #include #include #include #include #include #i

    11、nclude #include #include #include #include #define MAXLINE 4096int main() int sock;/server socket struct sockaddr_in server;/server socketaddr_in struct sockaddr_in client; char msgsock;/client socket int namelen;/socket addr length int bReuseaddr=1; int ret=-9; int client_id=0; /创建socket sock=socke

    12、t(AF_INET,SOCK_STREAM,0); if(sock0) printf(socket errorn); return 0; printf(sock-ret=%dn,sock); /网络字节序 server.sin_family=AF_INET; server.sin_addr.s_addr=INADDR_ANY; server.sin_port=htons(6000);/.MYPORT bzero(&(server.sin_zero),8); setsockopt(sock,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,siz

    13、eof(int); /bind if(ret=bind(sock,(struct sockaddr *)&server,sizeof(struct sockaddr)0)/*bind() printf(bind errorn); return 0; printf(bind-ret=%dn,ret); ret=-9; if(ret=listen(sock,100)0)/*listen() printf(listen errorn); return 0; printf(listen-ret=%dn,ret); while(1) namelen=sizeof(struct sockaddr_in);

    14、/sockaddr_in:地址信息 if(msgsock=accept(sock,(struct sockaddr *)&client,&namelen)=(n=recv(sockettemp,data_buf,MAXLINE,0) continue; else send(sockettemp,ch_send_back,strlen(ch_send_back),0); close(sockettemp); break; close(sockettemp); printf(SOCKET END =n); exit(0); else/father close(msgsock); usleep(10

    15、); return 0;Server02:/*/#include #include #include #include #include #include #include #include #include #include #include #define MAXLINE 4096void proc_child(int SIGNO) int pid = -1; int stat; pid = waitpid(-1, &stat, WNOHANG);int main() int sock;/server socket struct sockaddr_in server;/server soc

    16、ketaddr_in struct sockaddr_in client; char msgsock;/client socket int namelen;/socket addr length int bReuseaddr=1; int ret=-9; int client_id=0; /创建socket sock=socket(AF_INET,SOCK_STREAM,0); if(sock0) printf(socket errorn); return 0; printf(sock-ret=%dn,sock); /网络字节序 server.sin_family=AF_INET; serve

    17、r.sin_addr.s_addr=INADDR_ANY; server.sin_port=htons(6000);/.MYPORT bzero(&(server.sin_zero),8); setsockopt(sock,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(int); /bind if(ret=bind(sock,(struct sockaddr *)&server,sizeof(struct sockaddr)0)/*bind() printf(bind errorn); return 0; printf(bin

    18、d-ret=%dn,ret); ret=-9; if(ret=listen(sock,100)0)/*listen() printf(listen errorn); return 0; printf(listen-ret=%dn,ret); signal(SIGCHLD, proc_child); /signal(SIGCHLD, SIG_IGN); while(1) namelen=sizeof(struct sockaddr_in);/sockaddr_in:地址信息 if(msgsock=accept(sock,(struct sockaddr *)&client,&namelen)=(

    19、n=recv(sockettemp,data_buf,MAXLINE,0) continue; else send(sockettemp,ch_send_back,strlen(ch_send_back),0); close(sockettemp); break; close(sockettemp); printf(SOCKET END =n); exit(0); else/father close(msgsock); usleep(10); return 0;void proc_child(int SIGNO) int pid = -1; int stat; pid = waitpid(-1

    20、, &stat, WNOHANG);Server03:/*/#include #include #include #include #include #include #include #include #include #include #include #define MAXLINE 4096void proc_child(int SIGNO) int pid = -1; int stat; pid = waitpid(-1, &stat, WNOHANG);int main() int sock;/server socket struct sockaddr_in server;/serv

    21、er socketaddr_in struct sockaddr_in client; char msgsock;/client socket int namelen;/socket addr length int bReuseaddr=1; int ret=-9; int client_id=0; /创建socket sock=socket(AF_INET,SOCK_STREAM,0); if(sock0) printf(socket errorn); return 0; printf(sock-ret=%dn,sock); /网络字节序 server.sin_family=AF_INET;

    22、 server.sin_addr.s_addr=INADDR_ANY; server.sin_port=htons(6000);/.MYPORT bzero(&(server.sin_zero),8); setsockopt(sock,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(int); /bind if(ret=bind(sock,(struct sockaddr *)&server,sizeof(struct sockaddr)0)/*bind() printf(bind errorn); return 0; printf(bind-ret=%


    注意事项

    本文(linux环境下c语言书写socket服务器程序的步骤和注意事项.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开