C++实现 socket 传输任意字符串,在网上看到了许多很不错的代码,但大都是一端发送字符串,另外一端循环接收字符串,并没有对字符串的长度进行比较,试想:若在传完字符串后,还有其他的数据传送,那么在这样的情况下,接收端循环接收字符串就存在很大的弊端,因此在这里实现的是先将字符串的长度传送到接收端,而后紧接着传输字符串本身,这样在接收端就能先接收到字符串的长度,然后根据接收的长度接收字符串本身的数据。

客户端实现如下:

client.cpp


  1. #include <iostream>
  2. #include <;
  3. #include <string>
  4. #include <;
  5. #include "TCPClient.h"
  6. TCPClient tcp;
  7. using namespace std;
  8. void sig_exit(int s)
  9. {
  10. ();
  11. exit(0);
  12. }
  13. int main(int argc, char *argv[])
  14. {
  15. string message;
  16. getline(cin,message);
  17. signal(SIGINT, sig_exit);
  18. ("127.0.0.1",11999);
  19. (message);
  20. string rec = ();
  21. if( rec != "" )
  22. {
  23. cout << "Server Response:" << rec << endl;
  24. }
  25. return 0;
  26. }

TCPClient.cpp


  1. #include "TCPClient.h"
  2. TCPClient::TCPClient(){
  3. sock = -1;
  4. port = 0;
  5. address = "";
  6. }
  7. bool TCPClient::setup(string address , int port){
  8. if(sock == -1)
  9. {
  10. sock = socket(AF_INET , SOCK_STREAM , 0);
  11. if (sock == -1)
  12. {
  13. cout << "Could not create socket" << endl;
  14. }
  15. }
  16. if(inet_addr()) == (unsigned)-1)
  17. {
  18. struct hostent *he;
  19. struct in_addr **addr_list;
  20. if ( (he = gethostbyname( addre() ) ) == NULL)
  21. {
  22. herror("gethostbyname");
  23. cout<<"Failed to resolve hostname\n";
  24. return false;
  25. }
  26. addr_list = (struct in_addr **) he->h_addr_list;
  27. for(int i = 0; addr_list[i] != NULL; i++)
  28. {
  29. = *addr_list[i];
  30. break;
  31. }
  32. }
  33. else
  34. {
  35. .s_addr = inet_addr( addre() );
  36. }
  37. = AF_INET;
  38. = htons( port );
  39. if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
  40. {
  41. perror("connect failed. Error");
  42. return false;
  43. }
  44. return true;
  45. }
  46. bool TCPClient::Send(string data){
  47. cout<< "the data is:"<< data <<endl;
  48. if(sock != -1) {
  49. int length = da();
  50. if(send(sock, &length, sizeof(int), 0 ) < 0 ){
  51. cout << "Send length failed : " << endl;
  52. return false;
  53. }
  54. if( send(sock , da() , da() , 0) < 0){
  55. cout << "Send failed : " << data << endl;
  56. return false;
  57. }
  58. }
  59. else
  60. return false;
  61. return true;
  62. }
  63. string TCPClient::receive(int size){
  64. int length = 0;
  65. recv(sock,&length,sizeof(int),0);
  66. char* message = (char*)malloc(length+1);
  67. memset(message, 0, length+1);
  68. recv(sock,message,length,0);
  69. string reply = message;
  70. free(message);
  71. return reply;
  72. }
  73. void TCPClient::exit()
  74. {
  75. close( sock );
  76. }

TCPClient.h


  1. #ifndef TCP_CLIENT_H
  2. #define TCP_CLIENT_H
  3. #include <iostream>
  4. #include <;
  5. #include <;
  6. #include <uni;
  7. #include <;
  8. #include <sy;
  9. #include <sy;
  10. #include <netine;
  11. #include <arpa;
  12. #include <ne;
  13. #include <ne;
  14. #include <vector>
  15. #include "../Agen;
  16. using namespace std;
  17. class TCPClient
  18. {
  19. private:
  20. int sock;
  21. std::string address;
  22. int port;
  23. struct sockaddr_in server;
  24. public:
  25. TCPClient();
  26. bool setup(string address, int port);
  27. bool Send(string data);
  28. string receive(int size = 4096);
  29. string read();
  30. void exit();
  31. };
  32. #endif

在Linux 下进行编译,其编译命令如下:

g++ -Wall -o client client.cpp TCPClient.cpp -std=c++11 -lpthread

服务端代码如下:


  1. #include <iostream>
  2. #include "TCPServer.h"
  3. TCPServer tcp;
  4. int main()
  5. {
  6. //设置服务器端口
  7. (11999);
  8. ();
  9. return 0;
  10. }

TCPClient.cpp


  1. #include "TCPServer.h"
  2. void* TCPServer::Task(void *arg)
  3. {
  4. int sock = (long)arg;
  5. pthread_detach(pthread_self());
  6. //接收客户端字符串
  7. if(sock != -1){
  8. int length = 0;
  9. if(sizeof(int)!=recv(sock,&length,sizeof(int),0)){
  10. printf("recv length error...");
  11. }
  12. char* message = (char*)malloc(length+1);//length + 1 是保证传输的字符串中结束符的存在
  13. memset(message, 0 , length);//清空缓冲区的内容
  14. if(length != recv(sock,message,length,0)){
  15. printf("recv string error...");
  16. }
  17. //以下将收到的字符串加上 --from server!!! 后发送回客户端
  18. string returnstr = message;
  19. returnstr += " --from server!!!";
  20. int returnstr_length = re();
  21. send(sock, &returnstr_length, sizeof(int),0);//先将字符串的长度发送给客户端
  22. send(sock,re(),re(),0);
  23. }
  24. return 0;
  25. }
  26. void TCPServer::setup(int port)
  27. {
  28. sockfd=socket(AF_INET,SOCK_STREAM,0);
  29. memset(&serverAddress,0,sizeof(serverAddress));
  30. ;
  31. (INADDR_ANY);
  32. (port);
  33. bind(sockfd,(struct sockaddr *)&serverAddress, sizeof(serverAddress));
  34. listen(sockfd,5);
  35. }
  36. void TCPServer::receive()
  37. {
  38. while(1)
  39. {
  40. socklen_t sosize = sizeof(clientAddress);
  41. newsockfd = accept(sockfd,(struct sockaddr*)&clientAddress,&sosize);
  42. inet_ntoa);
  43. pthread_create(&serverThread,NULL,&Task,(void *)newsockfd);
  44. }
  45. close(sockfd);
  46. close(newsockfd);
  47. }

TCPClient.h


  1. #ifndef TCP_SERVER_H
  2. #define TCP_SERVER_H
  3. #include <iostream>
  4. #include <;
  5. #include <;
  6. #include <;
  7. #include <sy;
  8. #include <sy;
  9. #include <netine;
  10. #include <;
  11. #include <arpa;
  12. #include <;
  13. #include <uni;
  14. using namespace std;
  15. #define MAXPACKETSIZE 4096
  16. class TCPServer
  17. {
  18. public:
  19. int sockfd, newsockfd, n, pid;
  20. struct sockaddr_in serverAddress;
  21. struct sockaddr_in clientAddress;
  22. pthread_t serverThread;
  23. void setup(int port);
  24. void receive();
  25. private:
  26. static void * Task(void * argv);
  27. };
  28. #endif

Server 端编译的命令如下:

g++ -Wall -o server TCPServer.cpp -std=c++11 -lpthread

最后实现的效果如下所示:

1.《如何在类里传递字符串》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

2.《如何在类里传递字符串》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/3218849.html