C++实现 socket 传输任意字符串,在网上看到了许多很不错的代码,但大都是一端发送字符串,另外一端循环接收字符串,并没有对字符串的长度进行比较,试想:若在传完字符串后,还有其他的数据传送,那么在这样的情况下,接收端循环接收字符串就存在很大的弊端,因此在这里实现的是先将字符串的长度传送到接收端,而后紧接着传输字符串本身,这样在接收端就能先接收到字符串的长度,然后根据接收的长度接收字符串本身的数据。
客户端实现如下:
client.cpp
- #include <iostream>
- #include <;
- #include <string>
- #include <;
- #include "TCPClient.h"
- TCPClient tcp;
- using namespace std;
- void sig_exit(int s)
- {
- ();
- exit(0);
- }
- int main(int argc, char *argv[])
- {
- string message;
- getline(cin,message);
- signal(SIGINT, sig_exit);
- ("127.0.0.1",11999);
- (message);
- string rec = ();
- if( rec != "" )
- {
- cout << "Server Response:" << rec << endl;
- }
- return 0;
- }
TCPClient.cpp
- #include "TCPClient.h"
- TCPClient::TCPClient(){
- sock = -1;
- port = 0;
- address = "";
- }
- bool TCPClient::setup(string address , int port){
- if(sock == -1)
- {
- sock = socket(AF_INET , SOCK_STREAM , 0);
- if (sock == -1)
- {
- cout << "Could not create socket" << endl;
- }
- }
- if(inet_addr()) == (unsigned)-1)
- {
- struct hostent *he;
- struct in_addr **addr_list;
- if ( (he = gethostbyname( addre() ) ) == NULL)
- {
- herror("gethostbyname");
- cout<<"Failed to resolve hostname\n";
- return false;
- }
- addr_list = (struct in_addr **) he->h_addr_list;
- for(int i = 0; addr_list[i] != NULL; i++)
- {
- = *addr_list[i];
- break;
- }
- }
- else
- {
- .s_addr = inet_addr( addre() );
- }
- = AF_INET;
- = htons( port );
- if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
- {
- perror("connect failed. Error");
- return false;
- }
- return true;
- }
- bool TCPClient::Send(string data){
- cout<< "the data is:"<< data <<endl;
- if(sock != -1) {
- int length = da();
- if(send(sock, &length, sizeof(int), 0 ) < 0 ){
- cout << "Send length failed : " << endl;
- return false;
- }
- if( send(sock , da() , da() , 0) < 0){
- cout << "Send failed : " << data << endl;
- return false;
- }
- }
- else
- return false;
- return true;
- }
- string TCPClient::receive(int size){
- int length = 0;
- recv(sock,&length,sizeof(int),0);
- char* message = (char*)malloc(length+1);
- memset(message, 0, length+1);
- recv(sock,message,length,0);
- string reply = message;
- free(message);
- return reply;
- }
- void TCPClient::exit()
- {
- close( sock );
- }
TCPClient.h
- #ifndef TCP_CLIENT_H
- #define TCP_CLIENT_H
- #include <iostream>
- #include <;
- #include <;
- #include <uni;
- #include <;
- #include <sy;
- #include <sy;
- #include <netine;
- #include <arpa;
- #include <ne;
- #include <ne;
- #include <vector>
- #include "../Agen;
- using namespace std;
- class TCPClient
- {
- private:
- int sock;
- std::string address;
- int port;
- struct sockaddr_in server;
- public:
- TCPClient();
- bool setup(string address, int port);
- bool Send(string data);
- string receive(int size = 4096);
- string read();
- void exit();
- };
- #endif
在Linux 下进行编译,其编译命令如下:
g++ -Wall -o client client.cpp TCPClient.cpp -std=c++11 -lpthread
服务端代码如下:
- #include <iostream>
- #include "TCPServer.h"
- TCPServer tcp;
- int main()
- {
- //设置服务器端口
- (11999);
- ();
- return 0;
- }
TCPClient.cpp
- #include "TCPServer.h"
- void* TCPServer::Task(void *arg)
- {
- int sock = (long)arg;
- pthread_detach(pthread_self());
- //接收客户端字符串
- if(sock != -1){
- int length = 0;
- if(sizeof(int)!=recv(sock,&length,sizeof(int),0)){
- printf("recv length error...");
- }
- char* message = (char*)malloc(length+1);//length + 1 是保证传输的字符串中结束符的存在
- memset(message, 0 , length);//清空缓冲区的内容
- if(length != recv(sock,message,length,0)){
- printf("recv string error...");
- }
- //以下将收到的字符串加上 --from server!!! 后发送回客户端
- string returnstr = message;
- returnstr += " --from server!!!";
- int returnstr_length = re();
- send(sock, &returnstr_length, sizeof(int),0);//先将字符串的长度发送给客户端
- send(sock,re(),re(),0);
- }
- return 0;
- }
- void TCPServer::setup(int port)
- {
- sockfd=socket(AF_INET,SOCK_STREAM,0);
- memset(&serverAddress,0,sizeof(serverAddress));
- ;
- (INADDR_ANY);
- (port);
- bind(sockfd,(struct sockaddr *)&serverAddress, sizeof(serverAddress));
- listen(sockfd,5);
- }
- void TCPServer::receive()
- {
- while(1)
- {
- socklen_t sosize = sizeof(clientAddress);
- newsockfd = accept(sockfd,(struct sockaddr*)&clientAddress,&sosize);
- inet_ntoa);
- pthread_create(&serverThread,NULL,&Task,(void *)newsockfd);
- }
- close(sockfd);
- close(newsockfd);
- }
TCPClient.h
- #ifndef TCP_SERVER_H
- #define TCP_SERVER_H
- #include <iostream>
- #include <;
- #include <;
- #include <;
- #include <sy;
- #include <sy;
- #include <netine;
- #include <;
- #include <arpa;
- #include <;
- #include <uni;
- using namespace std;
- #define MAXPACKETSIZE 4096
- class TCPServer
- {
- public:
- int sockfd, newsockfd, n, pid;
- struct sockaddr_in serverAddress;
- struct sockaddr_in clientAddress;
- pthread_t serverThread;
- void setup(int port);
- void receive();
- private:
- static void * Task(void * argv);
- };
- #endif
Server 端编译的命令如下:
g++ -Wall -o server TCPServer.cpp -std=c++11 -lpthread
最后实现的效果如下所示:
1.《如何在类里传递字符串》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《如何在类里传递字符串》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/keji/3218849.html