




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于TCP(面向连接)的socket编程,分为客户端和服务器端。客户端的流程如下:(1)创建套接字(socket)(2)向服务器发出连接请求(connect)(3)和服务器端进行通信(send/recv)(4)关闭套接字服务器端的流程如下:(1)创建套接字(socket)(2)将套接字绑定到一个本地地址和端口上(bind)(3)将套接字设为监听模式,准备接收客户端请求(listen)(4)等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)(5)用返回的套接字和客户端进行通信(send/recv)(6)返回,等待另一个客户请求。(7)关闭套接字。下面通过一个具体例子讲解一下具体的过程和相关的函数。客户端代码,运行于vs2008cppview plaincopy1. /ClientTest.cpp:定义控制台应用程序的入口点。2. /3. 4. #includestdafx.h5. #include6. #include7. #include8. 9. #defineSERVER_PORT5208/侦听端口10. 11. 12. int_tmain(intargc,_TCHAR*argv)13. 14. WORDwVersionRequested;15. WSADATAwsaData;16. intret;17. SOCKETsClient;/连接套接字18. structsockaddr_insaServer;/服务器地址信息19. char*ptr;20. BOOLfSuccess=TRUE;21. 22. /WinSock初始化23. wVersionRequested=MAKEWORD(2,2);/希望使用的WinSockDLL的版本24. ret=WSAStartup(wVersionRequested,&wsaData);/加载套接字库25. if(ret!=0)26. 27. printf(WSAStartup()failed!n);28. /return0;29. 30. /确认WinSockDLL支持版本2.231. if(LOBYTE(wsaData.wVersion)!=2|HIBYTE(wsaData.wVersion)!=2)32. 33. WSACleanup();/释放为该程序分配的资源,终止对winsock动态库的使用34. printf(InvalidWinSockversion!n);35. /return0;36. 37. 38. /创建Socket,使用TCP协议39. sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);40. if(sClient=INVALID_SOCKET)41. 42. WSACleanup();43. printf(socket()failed!n);44. /return0;45. 46. 47. /构建服务器地址信息48. saServer.sin_family=AF_INET;/地址家族49. saServer.sin_port=htons(SERVER_PORT);/注意转化为网络节序50. saServer.sin_addr.S_un.S_addr=inet_addr(127.0.0.1);51. 52. /连接服务器53. ret=connect(sClient,(structsockaddr*)&saServer,sizeof(saServer);54. if(ret=SOCKET_ERROR)55. 56. printf(connect()failed!n);57. closesocket(sClient);/关闭套接字58. WSACleanup();59. /return0;60. 61. 62. 63. charsendMessage=ZhongXingPengYue;64. ret=send(sClient,(char*)&sendMessage,sizeof(sendMessage),0);65. if(ret=SOCKET_ERROR)66. 67. printf(send()failed!n);68. 69. else70. printf(clientinfohasbeensent!);71. charrecvBuf100;72. recv(sClient,recvBuf,100,0);73. printf(%sn,recvBuf);74. closesocket(sClient);/关闭套接字75. WSACleanup();76. getchar();77. /return0;78. 79. 80. cppview plaincopy1. 第一步,加载套接字。使用WSAStartup 函数,如:ret = WSAStartup(wVersionRequested, &wsaData)。WSAStartup函数的原型为cppview plaincopy1. intWSAStartup(WORDwVersionRequested,LPWSADATAlpWSAData)第一参数wVersionRequested,用来指定准备加载的winsock库的版本。利用MAKEWORD(x,y)宏来赋值。x是高位字节,表示副版本号;y是低位字节,表示主版本号。MAKEWORD(2, 2)表示版本号为2.2。第二个参数是指向WSADATA结构的指针,是一个返回值,保存了库版本的有关信息。 第二步,创建套接字。使用socket函数,如:sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)。socket函数的原型为:cppview plaincopy1. SOCKETsocket(intaf,inttype,intprotocol);第一个参数,指定地址族,对于TCP/IP协议的套接字,只能为AF_INET;第二个参数,指定socket类型,SOCK_STREAM指产生流式套接字,SOCK_DGRAM指产生数据报套接字,TCP/IP协议使用SOCK_STREAM。第三个参数,与特定的地址家族相关的协议,TCP协议一般为IPPROTO_TCP。也可以写0,那么系统会根据地址格式和套接字类别,自动选择一个适合的协议。如果socket创建成功,则返回一个新的SOCKET数据类型的套接字描述符;若失败,则返回INVALID_SOCKET,由此可以判断是否创建成功。 第三步,连接服务器。使用connect函数,如:ret = connect(sClient, (struct sockaddr *)&saServer, sizeof(saServer)。connect函数函数原型为csharpview plaincopy1. intconnect(SOCKETs,conststructsockaddrFAR*name,intnamelen);第一个参数是将在上面建立连接的那个套接字的描述符,即之前创建socket的返回值sClient。第二个参数是要连接的服务器端的地址信息。它是一个结构体类型struct sockaddr_in ,需要在调用connect函数之前构建服务器地址信息。sockaddr_in的定义如下:cppview plaincopy1. structsockaddr_in2. 3. shortsin_family;4. 5. unsignedshortsin_port;6. 7. structin_addrsin_addr;8. 9. charsin_zero810. 11. ;设置服务器端口时,用到htons函数,该函数把一个u_short类型的值从主机字节顺序转换为TCP/IP网络字节顺序,因为不同的计算机存放多字节的顺序不同(基于Intel CPU是高字节存放在低地址,低字节存放在高地址),所以网络中不同主机间通信时,要统一采用网络字节顺序。设置服务器IP地址时,使用到inet_addr函数,它是将点分十进制的IP地址的字符串转换成unsigned long型。inet_ntoa函数做相反的转换。第三个参数是服务器端地址结构体的大小。 第四步,发送。使用send函数向服务器发送数据,如:ret = send (sClient, (char *)&sendMessage, sizeof(sendMessage), 0)。send函数的原型为cppview plaincopy1. intsend(SOCKETs,constcharFAR*buf,intlen,intflags);第一个参数,是一个与服务器已经建立连接的套接字。第二个参数,指向包含要发送的数据的缓冲区的指针。第三个参数,是所指向的缓冲区的长度。准确的说,应该是所要发送的数据的长度,因为不是缓冲区的所有数据都要同时发送。第四个参数,它设定的值将影响函数的行为,一般将其设置为0即可。如果发送失败,send会返回SOCKET_ERROR,由此可以判断发送是否成功。 第五步,接收。使用recv函数接收服务器发过来的数据,如recv(sClient,recvBuf,100,0)。recv函数的原型为cppview plaincopy1. intrecv(SOCKETs,constcharFAR*buf,intlen,intflags);recv函数的参数的含义和send函数参数含义差不多,只是第二个参数是指向用来保存接收数据的缓冲区的指针。recv函数的返回值应该是所接收的数据的长度,如果返回SOCKET_ERROR表示接收失败;返回0表示服务器端关闭连接。 第六步,关闭socket,释放资源。使用closesocket函数关闭套接字,如closesocket(sClient);使用WSACleanup函数释放为该程序分配的资源,终止对winsock动态库的使用,如WSACleanup();服务器端代码,运行于vs2008cppview plaincopy1. /ServerTest.cpp:定义控制台应用程序的入口点。2. /3. 4. #includestdafx.h5. #include6. #include7. 8. #defineSERVER_PORT5208/侦听端口9. 10. int_tmain(intargc,_TCHAR*argv)11. 12. WORDwVersionRequested;13. WSADATAwsaData;14. intret,nLeft,length;15. SOCKETsListen,sServer;/侦听套接字,连接套接字16. structsockaddr_insaServer,saClient;/地址信息17. char*ptr;/用于遍历信息的指针18. /WinSock初始化19. wVersionRequested=MAKEWORD(2,2);/希望使用的WinSockDLL的版本20. ret=WSAStartup(wVersionRequested,&wsaData);21. if(ret!=0)22. 23. printf(WSAStartup()failed!n);24. /return0;25. 26. /创建Socket,使用TCP协议27. sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);28. if(sListen=INVALID_SOCKET)29. 30. WSACleanup();31. printf(socket()faild!n);32. /return0;33. 34. /构建本地地址信息35. saServer.sin_family=AF_INET;/地址家族36. saServer.sin_port=htons(SERVER_PORT);/注意转化为网络字节序37. saServer.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/使用INADDR_ANY指示任意地址38. 39. /绑定40. ret=bind(sListen,(structsockaddr*)&saServer,sizeof(saServer);41. if(ret=SOCKET_ERROR)42. 43. printf(bind()faild!code:%dn,WSAGetLastError();44. closesocket(sListen);/关闭套接字45. WSACleanup();46. /return0;47. 48. 49. /侦听连接请求50. ret=listen(sListen,5);51. if(ret=SOCKET_ERROR)52. 53. printf(listen()faild!code:%dn,WSAGetLastError();54. closesocket(sListen);/关闭套接字55. /return0;56. 57. 58. printf(Waitingforclientconnecting!n);59. printf(Tips:Ctrl+ctoquit!n);60. /阻塞等待接受客户端连接61. while(1)/循环监听客户端,永远不停止,所以,在本项目中,我们没有心跳包。62. 63. length=sizeof(saClient);64. sServer=accept(sListen,(structsockaddr*)&saClient,&length);65. if(sServer=INVALID_SOCKET)66. 67. printf(accept()faild!code:%dn,WSAGetLastError();68. closesocket(sListen);/关闭套接字69. WSACleanup();70. return0;71. 72. 73. charsendMessage=helloclient;/发送信息给客户端74. send(sServer,sendMessage,strlen(sendMessage)+1,0);75. 76. charreceiveMessage5000;77. nLeft=sizeof(receiveMessage);78. ptr=(char*)&receiveMessage;79. while(nLeft0)80. 81. /接收数据82. ret=recv(sServer,ptr,5000,0);83. if(ret=SOCKET_ERROR)84. 85. printf(recv()failed!n);86. return0;87. 88. if(ret=0)/客户端已经关闭连接89. 90. printf(Clienthasclosedtheconnectionn);91. break;92. 93. nLeft-=ret;94. ptr+=ret;95. 96. printf(receivemessage:%sn,receiveMessage);/打印我们接收到的消息。97. 98. 99. 100. /closesocket(sListen);101. /closesocket(sServer);102. /WSACleanup();103. return0;104. 第一步,加载套接字库,和客户端得加载套接字一样。 第二步,创建监听套接字,sListen=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);仍然使用的是socket函数。 第三步,绑定。使用bind函数,该函数的作用是将一个创建好的套接字绑定到本地的某个地址和端口上,该函数的原型为:cppview plaincopy1. intbind(SOCKETs,conststructsockaddrFAR*name,intnamelen);第一个参数,指定要绑定的套接字;第二个参数,指定该套接字的地址信息,这里即服务器的地址信息,它仍是指向struct sockaddr_in类型的结构体的指针。这个结构体和客户端调用connect函数之前构建服务器地址信息的一样。其中INADDR_ANY 是指示任意地址,因为服务器含有可能多个网卡,可能有多个IP地址,这边指选择一个任意可用的地址。第三个参数,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- (正式版)DB15∕T 3665.1-2024 《玉米秸秆饲料化利用技术规程 第1部分:玉米秸秆膨化饲料加工》
- 动态中考试题及答案
- 公益捐赠透明使用承诺书8篇
- 电气工考试题及答案
- 电焊科目考试题及答案
- 地形测量考试题及答案
- 行政固定资产管理系统配置方案
- 销售团队激励与考核策略设计手册
- 导尿术考试题及答案
- 护理生专业实务考试题库及答案
- 2025-2026年秋季学期各周国旗下讲话安排表+2025-2026学年上学期升旗仪式演讲主题安排表
- 2025年公务员(国考)之公共基础知识考试题库(带答案解析)
- 初级医学影像技术师考试试卷及答案2025年
- 幼儿园一日生活指引培训
- 中班健康运蔬菜喽
- 2025年护理核心制度试题及答案
- 宣传思想文化试题及答案
- 精神科木僵患者的护理
- 黄赌毒培训课件
- 肾动脉狭窄介入治疗讲课件
- 征迁岗位笔试题目及答案
评论
0/150
提交评论