




已阅读5页,还剩30页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
C+基于TCP和UDP的socket通信2011-08-18 12:445562人阅读评论(5)收藏举报sockettcpc+服务器streaminternet TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它事先为要发送的数据开辟好连接通道(三次握手),然后再进行数据发送;而UDP则不为IP提供可靠性,一般用于实时的视频流传输,像rtp、rtsp就是建立在udp的基础上的。 首先谈谈tcp socket tcp简单的三次握手过程如图, SYN(Synchronize Sequence Numbers):同步标志 ACK(Acknowledgement Number):确认标志 图中可以看出,三次握手的过程是在c的connect()和s的bind()、listen()、accept()函数中完成的,这样开辟了相对可靠的连接通道,来传输数据。UDP的socket编程过程如下图所示:下面翠花上代码啦!服务端:cppview plaincopy1. #include2. #include/windowssocket的头文件3. 4. #pragmacomment(lib,ws2_32.lib)/链接Winsock2.h的静态库文件5. 6. voidmain()7. 8. /初始化winsocket9. WORDwVersionRequested;10. WSADATAwsaData;11. interr;12. 13. wVersionRequested=MAKEWORD(1,1);/第一个参数为低位字节;第二个参数为高位字节14. 15. err=WSAStartup(wVersionRequested,&wsaData);/对winsockDLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源。16. if(err!=0)17. 18. return;19. 20. 21. if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)/LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容22. 23. WSACleanup();24. return;25. 26. 27. SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);/创建socket。AF_INET表示在Internet中通信;SOCK_STREAM表示socket是流套接字,对应tcp;0指定网络协议为TCP/IP28. 29. SOCKADDR_INaddrSrv;30. addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/htonl用来将主机字节顺序转换为网络字节顺序(tonetworklong)31. /INADDR_ANY就是指定地址为的地址,32. /表示不确定地址,或“任意地址”。”33. addrSrv.sin_family=AF_INET;34. addrSrv.sin_port=htons(4000);/htons用来将主机字节顺序转换为网络字节顺序(tonetworkshort)35. 36. bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/将本地地址绑定到所创建的socket上,以使在网络上标识该socket37. 38. listen(sockSrv,5);/socket监听,准备接受连接请求。39. 40. SOCKADDR_INaddrClient;41. intlen=sizeof(SOCKADDR);42. 43. while(1)44. 45. SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);/为一个连接请求提供服务。addrClient包含了发出连接请求的客户机IP地址信息;返回的新socket描述服务器与该客户机的连接46. 47. charsendBuf50;48. sprintf(sendBuf,Welcome%stohere!,inet_ntoa(addrClient.sin_addr);/inet_ntoa网络地址转换转点分十进制的字符串指针49. send(sockConn,sendBuf,strlen(sendBuf)+1,0);50. 51. charrecvBuf50;52. recv(sockConn,recvBuf,50,0);53. printf(%sn,recvBuf);54. 55. closesocket(sockConn);56. Sleep(2000);/2000毫秒57. 58. WSACleanup();59. 客户端:cppview plaincopy1. #include2. #include3. 4. #pragmacomment(lib,ws2_32.lib)5. 6. 7. voidmain()8. 9. WORDwVersionRequested;10. WSADATAwsaData;11. interr;12. 13. wVersionRequested=MAKEWORD(1,1);/第一个参数为低位字节;第二个参数为高位字节14. 15. err=WSAStartup(wVersionRequested,&wsaData);/对winsockDLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源。16. if(err!=0)17. 18. return;19. 20. 21. if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)/LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容22. 23. WSACleanup();24. return;25. 26. for(intindex=0;index+)27. 28. SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);29. 30. SOCKADDR_INaddrClt;/需要包含服务端IP信息31. addrClt.sin_addr.S_un.S_addr=inet_addr(0);/inet_addr将IP地址从点数格式转换成网络字节格式整型。32. addrClt.sin_family=AF_INET;33. addrClt.sin_port=htons(4000);34. 35. connect(sockClient,(SOCKADDR*)&addrClt,sizeof(SOCKADDR);/客户机向服务器发出连接请求36. charrecvBuf50;37. recv(sockClient,recvBuf,50,0);38. printf(myreplyis:%sn,recvBuf);39. 40. charsendBuf50;41. sprintf(sendBuf,%3d,index);42. strcat(sendBuf,servernodeof:yaopeng);43. send(sockClient,sendBuf,strlen(sendBuf)+1,0);44. 45. closesocket(sockClient);46. Sleep(2000);47. 48. WSACleanup();49. 对于tcp socket,有几点需要注意:一、TCP的TIME_WAIT状态(等待客户端的相应)注*TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟(MSL是最大分段生存期,指明TCP报文在Internet上最长生存时间) 当服务器端socket绑定本地地址并占用了端口,此时如果匆忙结束;或者连接的服务器异常退出,这个时候被占用的端口不能马上释放,需要TIME_WAIT。即便调用closesocket()一般也不会立即关闭socket,仍可继续重用该socket。所以重新启动服务器时可能会出现问题。例如MFC中在子窗口中实现socket通信,那么关闭子窗口再打开就会出问题了。 解决方法是在bind()之前添加setsockopt()函数,解除端口绑定。介绍setsockopt()之前我们再来回顾一下三次握手协议的具体流程:第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYNACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据。setsockopt()使用方法如下: 1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)调用closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL); 2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:BOOLbDontLinger = FALSE;setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL);更多setsockopt()函数用例可参考百度百科:/view/569217.htm二、对于大型文件,一般需要将其剁碎了一部分一部分的传。TCP不能保证接收方顺序的收到包,对于需要实时显示的文件可以在发送方发出包后设置来自接收方的响应,即对方收到前一个包后再发送下一个包。目前就这么多,各位看官有其他的注意事项拜托请留言补充,小弟感激啊。下面简单说下UDP socket UDP不能保证双方的可靠连接,容易出现丢包现象。 UDP的socket编程过程如下图所示:上代码了,哈哈。服务端:cppview plaincopy1. #include2. #include3. 4. #pragmacomment(lib,ws2_32.lib)5. 6. voidmain()7. 8. WORDwVersionRequested;9. WSADATAwsaData;10. interr;11. 12. wVersionRequested=MAKEWORD(1,1);13. 14. err=WSAStartup(wVersionRequested,&wsaData);15. if(err!=0)16. return;17. 18. 19. if(LOBYTE(wsaData.wVersion)!=1|20. HIBYTE(wsaData.wVersion)!=1)21. WSACleanup();22. return;23. 24. SOCKETsockSrv=socket(AF_INET,SOCK_DGRAM,0);25. 26. intlen=sizeof(SOCKADDR);27. 28. SOCKADDR_INfrom;29. SOCKADDR_INlocal;30. local.sin_addr.S_un.S_addr=htonl(INADDR_ANY);31. local.sin_family=AF_INET;32. local.sin_port=htons(27015);33. 34. inta=bind(sockSrv,(SOCKADDR*)&local,len);35. 36. 37. 38. while(1)39. 40. charrecvBuf50;41. recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&from,&len);/from收到客户端的IP信息42. printf(%sn,recvBuf);43. printf(%sn,inet_ntoa(local.sin_addr);44. charsendBuf50;45. sprintf(sendBuf,Welcome%stohere!,inet_ntoa(from.sin_addr);46. sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&from,len);47. 48. Sleep(2000);49. 50. closesocket(sockSrv);51. WSACleanup();52. 客户端:cppview plaincopy1. #include2. #include3. 4. #pragmacomment(lib,ws2_32.lib)5. 6. 7. voidmain()8. 9. WORDwVersionRequested;10. WSADATAwsaData;11. interr;12. 13. wVersionRequested=MAKEWORD(1,1);14. 15. err=WSAStartup(wVersionRequested,&wsaData);16. if(err!=0)17. return;18. 19. 20. if(LOBYTE(wsaData.wVersion)!=1|21. HIBYTE(wsaData.wVersion)!=1)22. WSACleanup();23. return;24. 25. 26. 27. for(intindex=0;index+)28. 29. SOCKETsockClient=socket(AF_INET,SOCK_DGRAM,0);30. 31. intlen=sizeof(SOCKADDR);32. 33. SOCKADDR_INlocal;34. local.sin_addr.S_un.S_addr=inet_addr(0);35. local.sin_family=AF_INET;36. local.sin_port=htons(27015);37. 38. charsendBuf30;39. sprintf(sendBuf,%3d,index);40. strcat(sendBuf,servernodeof:yaopeng);41. sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&local,len);42. 43. charrecvBuf50;44. recvfrom(sockClient,recvBuf,50,0,(SOCKADDR*)&local,&len);45. printf(myreplyis:%sn,recvBuf);46. printf(%sn,inet_ntoa(local.sin_addr);47. 48. closesocket(sockClient);49. Sleep(2000);50. WSACleanup();51. 52. C+基于TCP和UDP的socket通信2011-08-18 12:445562人阅读评论(5)收藏举报sockettcpc+服务器streaminternet TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它事先为要发送的数据开辟好连接通道(三次握手),然后再进行数据发送;而UDP则不为IP提供可靠性,一般用于实时的视频流传输,像rtp、rtsp就是建立在udp的基础上的。 首先谈谈tcp socket tcp简单的三次握手过程如图, SYN(Synchronize Sequence Numbers):同步标志 ACK(Acknowledgement Number):确认标志 图中可以看出,三次握手的过程是在c的connect()和s的bind()、listen()、accept()函数中完成的,这样开辟了相对可靠的连接通道,来传输数据。UDP的socket编程过程如下图所示:下面翠花上代码啦!服务端:cppview plaincopy1. #include2. #include/windowssocket的头文件3. 4. #pragmacomment(lib,ws2_32.lib)/链接Winsock2.h的静态库文件5. 6. voidmain()7. 8. /初始化winsocket9. WORDwVersionRequested;10. WSADATAwsaData;11. interr;12. 13. wVersionRequested=MAKEWORD(1,1);/第一个参数为低位字节;第二个参数为高位字节14. 15. err=WSAStartup(wVersionRequested,&wsaData);/对winsockDLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源。16. if(err!=0)17. 18. return;19. 20. 21. if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)/LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容22. 23. WSACleanup();24. return;25. 26. 27. SOCKETsockSrv=socket(AF_INET,SOCK_STREAM,0);/创建socket。AF_INET表示在Internet中通信;SOCK_STREAM表示socket是流套接字,对应tcp;0指定网络协议为TCP/IP28. 29. SOCKADDR_INaddrSrv;30. addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/htonl用来将主机字节顺序转换为网络字节顺序(tonetworklong)31. /INADDR_ANY就是指定地址为的地址,32. /表示不确定地址,或“任意地址”。”33. addrSrv.sin_family=AF_INET;34. addrSrv.sin_port=htons(4000);/htons用来将主机字节顺序转换为网络字节顺序(tonetworkshort)35. 36. bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR);/将本地地址绑定到所创建的socket上,以使在网络上标识该socket37. 38. listen(sockSrv,5);/socket监听,准备接受连接请求。39. 40. SOCKADDR_INaddrClient;41. intlen=sizeof(SOCKADDR);42. 43. while(1)44. 45. SOCKETsockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);/为一个连接请求提供服务。addrClient包含了发出连接请求的客户机IP地址信息;返回的新socket描述服务器与该客户机的连接46. 47. charsendBuf50;48. sprintf(sendBuf,Welcome%stohere!,inet_ntoa(addrClient.sin_addr);/inet_ntoa网络地址转换转点分十进制的字符串指针49. send(sockConn,sendBuf,strlen(sendBuf)+1,0);50. 51. charrecvBuf50;52. recv(sockConn,recvBuf,50,0);53. printf(%sn,recvBuf);54. 55. closesocket(sockConn);56. Sleep(2000);/2000毫秒57. 58. WSACleanup();59. 客户端:cppview plaincopy1. #include2. #include3. 4. #pragmacomment(lib,ws2_32.lib)5. 6. 7. voidmain()8. 9. WORDwVersionRequested;10. WSADATAwsaData;11. interr;12. 13. wVersionRequested=MAKEWORD(1,1);/第一个参数为低位字节;第二个参数为高位字节14. 15. err=WSAStartup(wVersionRequested,&wsaData);/对winsockDLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源。16. if(err!=0)17. 18. return;19. 20. 21. if(LOBYTE(wsaData.wVersion)!=1|HIBYTE(wsaData.wVersion)!=1)/LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容22. 23. WSACleanup();24. return;25. 26. for(intindex=0;index+)27. 28. SOCKETsockClient=socket(AF_INET,SOCK_STREAM,0);29. 30. SOCKADDR_INaddrClt;/需要包含服务端IP信息31. addrClt.sin_addr.S_un.S_addr=inet_addr(0);/inet_addr将IP地址从点数格式转换成网络字节格式整型。32. addrClt.sin_family=AF_INET;33. addrClt.sin_port=htons(4000);34. 35. connect(sockClient,(SOCKADDR*)&addrClt,sizeof(SOCKADDR);/客户机向服务器发出连接请求36. charrecvBuf50;37. recv(sockClient,recvBuf,50,0);38. printf(myreplyis:%sn,recvBuf);39. 40. charsendBuf50;41. sprintf(sendBuf,%3d,index);42. strcat(sendBuf,servernodeof:yaopeng);43. send(sockClient,sendBuf,strlen(sendBuf)+1,0);44. 45. closesocket(sockClient);46. Sleep(2000);47. 48. WSACleanup();49. 对于tcp socket,有几点需要注意:一、TCP的TIME_WAIT状态(等待客户端的相应)注*TIME_WAIT 状态最大保持时间是2 * MSL,也就是1-4分钟(MSL是最大分段生存期,指明TCP报文在Internet上最长生存时间) 当服务器端socket绑定本地地址并占用了端口,此时如果匆忙结束;或者连接的服务器异常退出,这个时候被占用的端口不能马上释放,需要TIME_WAIT。即便调用closesocket()一般也不会立即关闭socket,仍可继续重用该socket。所以重新启动服务器时可能会出现问题。例如MFC中在子窗口中实现socket通信,那么关闭子窗口再打开就会出问题了。 解决方法是在bind()之前添加setsockopt()函数,解除端口绑定。介绍setsockopt()之前我们再来回顾一下三次握手协议的具体流程:第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;第三次握手:客户端收到服务器的SYNACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。完成三次握手,客户端与服务器开始传送数据。setsockopt()使用方法如下: 1. 如果在已经处于 ESTABLISHED状态下的socket(一般由端口号和标志符区分)调用closesocket(一般不会立即关闭而经历TIME_WAIT的过程)后想继续重用该socket:BOOL bReuseaddr=TRUE;setsockopt(s,SOL_SOCKET ,SO_REUSEADDR,(const char*)&bReuseaddr,sizeof(BOOL); 2. 如果要已经处于连接状态的soket在调用closesocket后强制关闭,不经历TIME_WAIT的过程:BOOLbDontLinger = FALSE;setsockopt(s,SOL_SOCKET,SO_DONTLINGER,(const char*)&bDontLinger,sizeof(BOOL);更多setsockopt()函数用例可参考百度百科:/view/569217.htm二、对于大型文件,一般需要将其剁碎了一部分一部分的传。TCP不能保证接收方顺序的收到包,对于需要实时显示的文件可以在发送方发出包后设置来自接收方的响应,即对方收到前一个包后再发送下一个包。目前就这么多,各位看官有其他的注意事项拜托请留言补充,小弟感激啊。下面简单说下UDP socket UDP不能保证双方的可靠连接,容易出现丢包现象。 UDP的socket编程过程如下图所示:上代码了,哈哈。服务端:cppview plaincopy1. #include2. #include3. 4. #pragmacomment(lib,ws2_32.lib)5. 6. voidmain()7. 8. WORDwVersionRequested;9. WSADATAwsaData;10. interr;11. 12. wVersionRequested=MAKEWORD(1,1);13. 14. err=WSAStartup(wVersionRequested,&wsaData);15. if(err!=0)16. return;17. 18. 19. if(LOBYTE(wsaData.wVersion)!=1|20. HIBYTE(wsaData.wVersion)!=1)21. WSACleanup();22. return;23. 24. SOCKETsockSrv=socket(AF_INET,SOCK_DGRAM,0);25. 26. intlen=sizeof(SOCKADDR);27. 28. SOCKADDR_INfrom;29. SOCKADDR_INlocal;30. local.sin_addr.S_un.S_addr=htonl(INADDR_ANY);31. local.sin_family=AF_INET;32. local.sin_port=htons(27015);33. 34. inta=bind(sockSrv,(SOCKADDR*)&local,len);35. 36. 37. 38. while(1)39. 40. charrecvBuf50;41. recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&from,&len);/from收到客户端的IP信息42. printf(%sn,recvBuf);43. printf(%sn,inet_ntoa(local.sin_addr);44. charsendBuf50;45. sprintf(sendBuf,Welcome%stohere!,inet_ntoa(from.sin_addr);46. sendto(sockSrv,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&from,len);47. 48. Sleep(2000);49. 50. closesocket(sockSrv);51. WSACleanup();52. 客户端:cppview plaincopy1. #include2. #include3. 4. #pragmacomment(lib,ws2_32.lib)5. 6. 7. voidmain()8. 9. WORDwVersionRequested;10. WSADATAwsaData;11. interr;12. 13. wVersionRequested=MAKEWORD(1,1);14. 15. err=WSAStartup(wVersionRequested,&wsaData);16. if(err!=0)17. return;18. 19. 20. if(LOBYTE(wsaData.wVersion)!=1|21. HIBYTE(wsaData.wVersion)!=1)22. WSACleanup();23. return;24. 25. 26. 27. for(intindex=0;index+)28. 29. SOCKETsockClient=socket(AF_INET,SOCK_DGRAM,0);30. 31. intlen=sizeof(SOCKADDR);32. 33. SOCKADDR_INlocal;34. local.sin_addr.S_un.S_addr=inet_addr(0);35. local.sin_family=AF_INET;36. local.sin_port=htons(27015);37. 38. charsendBuf30;39. sprintf(sendBuf,%3d,index);40. strcat(sendBuf,servernodeof:yaopeng);41. sendto(sockClient,sendBuf,strlen(sendBuf)+1,0,(SOCKADDR*)&local,len);42. 43. charrecvBuf50;44. recvfrom(sockClient,recvBuf,50,0,(SOCKADDR*)&local,&len);45. printf(myreplyis:%sn,recvBuf);46. printf(%sn,inet_ntoa(local.sin_addr);47. 48. closesocket(sockClient);49. Sleep(2000);50. WSACleanup();51. 52. C+基于TCP和UDP的socket通信2011-08-18 12:445562人阅读评论(5)收藏举报sockettcpc+服务器streaminternet TCP和UDP属于传输层协议。其中TCP提供IP环境下的数据可靠传输,它事先为要发送的数据开辟好连接通道(三次握手),然后再进行数据发送;而UDP则不为IP提供可靠性,一般用于实时的视频流传输,像rtp、rtsp就是建立在udp的基础
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 景观栈道施工方案(3篇)
- 海盐无尘室施工方案(3篇)
- 悬浮厨柜施工方案(3篇)
- 物业SOP考试题库及答案
- 安徽省马鞍山市当涂县2024-2025学年高二上学期第二次月考思想政治考试题目及答案
- 心理班面试题目及答案
- 小学文学知识题目及答案
- 蓝色简约秋季开学工作部署
- 读书伴我快乐成长1500字(9篇)
- 名篇阅读课程设计:唐诗五首
- 股权估值协议书模板
- 顺丰快递合同
- 【家庭教育对幼儿性格形成的影响探究11000字(论文)】
- 《电化学原理与应用》课程教学大纲
- 新测绘法解读
- 热力发电厂课件04发电厂的热力系统
- 高海拔作业引发的危险
- 甲醇安全知识培训
- (对外)出租车驾驶员安全行车常识培训课件
- 高效时间管理-提升个人工作效率的方案
- 公安心理健康知识讲座
评论
0/150
提交评论