




已阅读5页,还剩10页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于Linux的socket编程模板 在网络编程编程中,我们经常会遇到这样一种C/S架构,服务器端(Server)监听客户端(Client)发送过来的命令,然后解析该命令,并做对应的处理,最后返回处理结果(例如成功或者失败及原因)给客户端。 最近,在Linux下做网络编程,涉及的就是上面的这种需求,简单地整理了下自己的代码,分享在这里吧,供初学者参考。 首先说一下编程思路吧。 在这种情况客户端必须实现的的接口有:连接服务器、发送、断开连接。 服务器端,有一个主线程,用于监听客户端的连接请求,一旦有新客户端连接,则创建一个新的socket及线程专门服务这个客户端。这个服务线程专门监听该客户端的命令,并且解析命令进行服务器,直到客户端断开连接或者发送关闭连接的命令。 另外,需要涉及一个通信协议,约定命令的包头、命令的识别码、命令的参数。 思路就说到这儿了,下面的相关代码,附件中有完整的代码,包含了Makefile文件。一、通信协议设计1. / 2. /COPYRIGHTNOTICE 3. /Copyright(c)2011,华中科技大学ticktick(版权声明) 4. /Allrightsreserved. 5. / 6. /fileCommand.h 7. /brief命令包声明文件 8. / 9. /定义各种TCP命令包以及相关结构体 10. / 11. /version1.0 12. /authorlujun 13. /E- 14. /date2011/08/21 15. / 16. / 17. /修订说明: 18. / 19. 20. #ifndefCOMMAND_H_ 21. #defineCOMMAND_H_ 22. 23. typedefunsignedcharuint8_t; 24. 25. /TCPCMDheaderlen 26. #defineTCP_CMD_HEADER_LEN8 27. 28. /CMDheader 29. staticuint8_tTCP_CMD_HEADER_STRTCP_CMD_HEADER_LEN=0xAA,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xFF; 30. 31. /maxusernamelen 32. #defineMAX_USER_NAME_LEN20 33. 34. /servercmdstruct 35. typedefenum_ServerCMD 36. 37. CMD_SAVE_USER_NAME,/saveusername 38. CMD_SAVE_USER_AGE,/saveuserage 39. 40. ServerCMD; 41. 42. /returncmd 43. typedefenum_ReturnCMD 44. 45. DVS_RETURN_SUCCESS=0, 46. DVS_RETURN_FAIL, 47. DVS_RETURN_TIMEOUT, 48. DVS_RETURN_INVLID_HEADER, 49. DVS_RETURN_INVLID_CMD, 50. DVS_RETURN_INVLID_PRM, 51. 52. ReturnCMD; 53. 54. /1bytesaligning 55. #pragmapack(push,1) 56. 57. /serverpackfromclient 58. typedefstruct_ServerPack 59. 60. /cmdheader 61. uint8_tcmdHeaderTCP_CMD_HEADER_LEN; 62. 63. /commandid 64. ServerCMDserverCMD; 65. 66. /cmdparam 67. union68. 69. /saveusername 70. struct71. 72. /username 73. charusernameMAX_USER_NAME_LEN; 74. 75. UserName; 76. 77. /saveuserage 78. struct79. 80. /userage 81. intuserage; 82. 83. UserAge; 84. 85. Parameters; 86. 87. ServerPack; 88. 89. /returnpackfromserver 90. typedefstruct_ReturnPack 91. 92. /cmdheader 93. uint8_tcmdHeaderTCP_CMD_HEADER_LEN; 94. 95. /returncmd 96. ReturnCMDreturnCMD; 97. 98. ReturnPack; 99. 100. #pragmapack(pop) 101. 102. #defineSERVER_PACK_LENsizeof(ServerPack) 103. #defineRETURN_PACK_LENsizeof(ReturnPack) 104. 105. #endif/COMMAND_H_ 二、客户端代码1. / 2. /COPYRIGHTNOTICE 3. /Copyright(c)2011,华中科技大学ticktick(版权声明) 4. /Allrightsreserved. 5. / 6. /fileclient.c 7. /brieftcp客户端代码 8. / 9. /实现tcp客户端的相关接口 10. / 11. /version1.0 12. /authorlujun 13. /E- 14. /date2011/08/21 15. / 16. / 17. /修订说明: 18. / 19. 20. #include 21. #include 22. #include 23. #include 24. #include 25. #include 26. #include 27. #includeclient.h 28. 29. /sockethandle 30. intg_hSocket; 31. 32. intconnect_server(char*destIp,intdestPort) 33. 34. intresult; 35. structsockaddr_inaddress; 36. 37. /createasocket 38. g_hSocket=socket(AF_INET,SOCK_STREAM,0); 39. 40. /setserveraddr 41. address.sin_family=AF_INET; 42. 43. /useserveripandlistenporttoconnect 44. address.sin_addr.s_addr=inet_addr(destIp); 45. address.sin_port=htons(destPort); 46. 47. /connecttcpserver 48. result=connect(g_hSocket,(structsockaddr*)&address,sizeof(address); 49. if(result=-1) 50. 51. printf(tcpclientcantconnectserver!n); 52. return-1; 53. 54. 55. return0; 56. 57. 58. intclose_connect() 59. 60. printf(closeconnectwithserver!n); 61. 62. close(g_hSocket); 63. 64. return0; 65. 66. 67. intsend_cmd(ServerPacksPack) 68. 69. intrecvBytes=0; 70. intsendBytes=0; 71. ReturnPackrPack; 72. 73. /addcmdheader 74. memcpy(sPack.cmdHeader,TCP_CMD_HEADER_STR,TCP_CMD_HEADER_LEN); 75. 76. /sendcmd 77. while(1) 78. 79. sendBytes=send(g_hSocket,(uint8_t*)&sPack,SERVER_PACK_LEN,0); 80. 81. if(sendBytes=SERVER_PACK_LEN) 82. 83. printf(successfullysendbytes%dn,SERVER_PACK_LEN); 84. break; 85. 86. elseif(sendBytes=0&errno!=EINTR&errno!=EWOULDBLOCK&errno!=EAGAIN) 87. 88. printf(disconnectedorothererrors!n); 89. return-1; 90. 91. else92. 93. continue; 94. 95. 96. 97. /recvprocessresultfromserver 98. while(1) 99. 100. recvBytes=recv(g_hSocket,(uint8_t*)&rPack,RETURN_PACK_LEN,0); 101. 102. if(recvBytes=RETURN_PACK_LEN) 103. 104. break; 105. 106. elseif(recvBytes=0&errno!=EINTR&errno!=EWOULDBLOCK&errno!=EAGAIN) 107. 108. printf(disconnectedorerroroccur!nclosethesocket!n); 109. return-1; 110. 111. else112. 113. continue; 114. 115. 116. 117. /checkheader 118. if(memcmp(rPack.cmdHeader,TCP_CMD_HEADER_STR,TCP_CMD_HEADER_LEN)!=0) 119. 120. printf(returnpackheadererrror!n); 121. return-2; 122. 123. 124. /getreturnstatus 125. if(rPack.returnCMD!=DVS_RETURN_SUCCESS) 126. 127. printf(returnstatus:fail!n); 128. return-3; 129. 130. 131. return0; 132. 133. 134. 三、服务器主线程代码1. / 2. /COPYRIGHTNOTICE 3. /Copyright(c)2011,华中科技大学ticktick(版权声明) 4. /Allrightsreserved. 5. / 6. /fileserver.c 7. /brieftcp服务器主线程代码 8. / 9. /实现tcp服务端监听线程相关函数 10. / 11. /version1.0 12. /authorlujun 13. /E- 14. /date2011/08/21 15. / 16. / 17. /修订说明: 18. / 19. 20. #include 21. #include 22. #include 23. 24. #include 25. #include 26. 27. #includeserverIf.h 28. 29. intg_hServerSocket; 30. 31. intopen_port(intlocalport) 32. 33. intresult; 34. intclientSocket,client_len; 35. 36. structsockaddr_inserver_addr; 37. structsockaddr_inclient_addr; 38. 39. /createasocketobjforserver 40. g_hServerSocket=socket(AF_INET,SOCK_STREAM,0); 41. 42. /bindtcpport 43. server_addr.sin_family=AF_INET; 44. server_addr.sin_addr.s_addr=htonl(INADDR_ANY); 45. server_addr.sin_port=htons(localport); 46. 47. result=bind(g_hServerSocket,(structsockaddr*)&server_addr,sizeof(server_addr); 48. if(result!=0) 49. 50. printf(tcpserverbinderror!n); 51. return-1; 52. 53. 54. /begintolisten 55. result=listen(g_hServerSocket,5); 56. if(result!=0) 57. 58. printf(tcpserverlistenerror!n); 59. return-1; 60. 61. 62. / 注: ServerEnv用于给服务线程传参,定义于serverIf.h中63. ServerEnvenv; 64. while(1) 65. 66. client_len=sizeof(client_addr); 67. clientSocket=accept(g_hServerSocket,(structsockaddr*)&client_addr,&client_len); 68. 69. if(clientSocket0) 70. 71. printf(tcpserveraccepterror!n); 72. return-1; 73. 74. 75. env.m_hSocket=clientSocket; 76. 77. /addnewtcpserverthread 78. add_new_tcp_process_thr(&env); 79. 80. 81. return0; 82. 83. 84. intclose_port() 85. 86. printf(closeserverport,stoplisten!n); 87. 88. close(g_hServerSocket); 89. 90. return0; 91. 四、服务器端服务线程代码1. / 2. /COPYRIGHTNOTICE 3. /Copyright(c)2011,华中科技大学ticktick(版权声明) 4. /Allrightsreserved. 5. / 6. /fileserverIf.c 7. /brieftcp服务线程代码 8. / 9. /实现tcp服务线程相关接口 10. / 11. /version1.0 12. /authorlujun 13. /E- 14. /date2011/08/21 15. / 16. / 17. /修订说明: 18. / 19. 20. #includeserverIf.h 21. #include./include/Command.h 22. #include 23. #include 24. #include 25. #include 26. 27. intadd_new_tcp_process_thr(ServerEnv*envp) 28. 29. pthread_ttcpThr; 30. 31. if(pthread_create(&tcpThr,NULL,tcpServerThrFxn,envp) 32. 33. printf(tcpthreadcreatefail!n); 34. return-1; 35. 36. 37. printf(tcpthreadhasbeencreated!n); 38. 39. return0; 40. 41. 42. intsave_user_name(char*pUsername) 43. 44. printf(ok,usernamesaved,username=%sn,pUsername); 45. 46. return0; 47. 48. 49. intsave_user_age(intage) 50. 51. printf(ok,useragesaved,userage=%dn,age); 52. 53. return0; 54. 55. 56. void*tcpServerThrFxn(void*arg) 57. 58. ServerEnv*envp=(ServerEnv*)arg; 59. intsocketfd=envp-m_hSocket; 60. intreturnBytes; 61. 62. ServerPacksPack; 63. ReturnPackrPack; 64. memcpy(rPack.cmdHeader,TCP_CMD_HEADER_STR,TCP_CMD_HEADER_LEN); 65. 66. while(1) 67. 68. /readcmdfromclient 69. returnBytes=recv(socketfd,(uint8_t*)&sPack,SERVER_PACK_LEN,0); 70. if(returnBytes=SERVER_PACK_LEN) 71. 72. /printf(ok,recv%dbytes!n,SERVER_PACK_LEN); 73. 74. elseif(returnBytes=0&errno!=EINTR&errno!=EWOULDBLOCK&errno!=EAGAIN) 75. 76. printf(disconnectedorerroroccur!errno=%dn,errno); 77. break; 78. 79. else80. 81. continue; 82. 83. 84. /checktheheader 85. if(memcmp(sPack.cmdHeader,TCP_CMD_HEADER_STR,TCP_CMD_HEADER_LEN)!=0) 86. 87. rPack.returnCMD=DVS_RETURN_INVLID_HEADER; 88. 89. /returnerrorinfotoclient 90. returnBytes=send(socketfd,(uint8_t*)&rPack,RETURN_PACK_LEN,0); 91. if(returnBytesRETURN_PACK_LEN) 92. 93. printf(senderror!n); 94. continue; 95. 96. 97. 98. /analysecmd 99. rPack.returnCMD=DVS_RETURN_SUCCESS; 100. switch(sPack.serverCMD) 101. 102. caseCMD_SAVE_USER_NAME: 103. 104. if(save_user_name(sPack.Parameters.UserName.username)!=0) 105. 106. rPack.returnCMD=DVS_RETURN_FAIL; 107. 108. 109. break; 110. caseCMD_SAVE_USER_AGE: 111. 112. if(save_user_age(sPack.Parameters.UserAge.userage)!=0) 113. 114. rPack.returnCMD=DVS_RETURN_FAIL; 115. 116. 117. break; 118. default: 119. 120. rPack.returnCMD=DVS_RETURN_INVLID_CMD; 121. 122. break; 123. 124. 125. /returnresultinfotoclient 126. returnBytes=send(socketfd,(uint8_t*)&rPack,RETURN_PACK_LEN,0); 127. if(returnBytesRETURN_PACK_LEN) 128. 129. printf(senderror!n); 130. continue; 131. 132. 133. 134. printf(closesessionsocket!); 135. 136. /closesocket 137. close(socketfd); 138. 139. return(void*)0; 140. 五、客户端测试代码1. / 2. /COPYRIGHTNOTICE 3. /Copyright(c)2011,华中科技大学ticktick(版权声明) 4. /Allrightsreserved. 5. / 6. /filemain.c 7. /brieftcp客户端测试代码 8. / 9. /实现tcp客户端测试 10. / 11. /version1.0 12. /authorlujun 13. /E- 14. /date2011/08/21 15. / 16. / 17. /修订说明: 18. / 19. 20. #include 21. 22. #includeclient.h 23. 24. #defineLOCAL_IP_STR 25. #defineDEST_IP_STR 26. #defineDEST_PORT8000 27. 28. intmain(intargc,char*argv) 29. 30. inti=0; 31. 32. printf(tcpteststart!n); 33. 34. if(connect
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 谱细胞抗体鉴定技术体系
- 秦汉时期名医成就与医学发展
- 先进特钢制造技术
- 我的秘密课文讲解
- 汽车设计核心要点解析
- 牙周病检查与诊断技术
- 软件销售年度汇报
- 人体器官大脑讲解
- 人工智能算法核心功能使用方法详解
- 胸心外科诊疗指南解读
- 江苏南京师范大学附属中学2024~2025学年高一下册6月期末考试数学试题学生卷
- 医院质控科服务质量职责
- 2025年物流无人机市场调研报告
- 中暑的临床表现和急救措施
- 党校班主任班级管理制度
- 检测类安全管理制度
- “十五五”住房和城乡建设发展规划
- 喉炎病人护理课件
- DB23-T2701-2020-森林抚育技术规程-黑龙江省
- T/GXSXFS 005-2021肉牛精料补充料
- 2025-2030中国生物质能行业市场深度调研及投资前景与投资策略研究报告
评论
0/150
提交评论