gpt4 book ai didi

c++:简单的TCP服务器不接受来自客户端的数据

转载 作者:行者123 更新时间:2023-11-28 05:53:03 24 4
gpt4 key购买 nike

我必须创建一个简单的 tcp 服务器,它从服务器接受一些命令并以某种方式响应它们。我从一件简单的事情开始,其中服务器接受来自客户端的任何内容作为命令,并向客户端响应 10 次 “响应您的命令” 作为答案。但即使这样也行不通。请帮忙。

服务器.cpp

# include <string.h>
# include <unistd.h>
# include <stdio.h>
# include <netdb.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <iostream>
# include <fstream>
# include <string.h>
# include <stdlib.h>
# include <string>
# include <pthread.h>
# include <dirent.h>

using namespace std;

void *task1(void *);

static int connFd;

int main(int argc, char* argv[])
{
int pId, portNo, listenFd;
socklen_t len; //store size of the address
bool loop = false;
struct sockaddr_in svrAdd, clntAdd;

pthread_t threadA[3];

if (argc < 2)
{
cerr << "Syntax : ./server <port>" << endl;
return 0;
}

portNo = atoi(argv[1]);

if((portNo > 65535) || (portNo < 2000))
{
cerr << "Please enter a port number between 2000 - 65535" << endl;
return 0;
}

//create socket
listenFd = socket(AF_INET, SOCK_STREAM, 0);

if(listenFd < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}

bzero((char*) &svrAdd, sizeof(svrAdd));

svrAdd.sin_family = AF_INET;
svrAdd.sin_addr.s_addr = INADDR_ANY;
svrAdd.sin_port = htons(portNo);

//bind socket
if(bind(listenFd, (struct sockaddr *)&svrAdd, sizeof(svrAdd)) < 0)
{
cerr << "Cannot bind" << endl;
return 0;
}

listen(listenFd, 5);

len = sizeof(clntAdd);

int noThread = 0;

while (noThread < 3)
{
cout << "Listening" << endl;

//this is where client connects. svr will hang in this mode until client conn
connFd = accept(listenFd, (struct sockaddr *)&clntAdd, &len);

if (connFd < 0)
{
cerr << "Cannot accept connection" << endl;
return 0;
}
else
{
cout << "Connection successful" << endl;
}

pthread_create(&threadA[noThread], NULL, task1, NULL);

noThread++;
}

for(int i = 0; i < noThread; i++)
{
pthread_join(threadA[i], NULL);
}
cout << "All threads have joined" << endl;
}

void *task1 (void *dummyPt)
{
cout << "Thread No: " << pthread_self() << endl;
char test[300];
char outbuf[300];
bzero(outbuf, 301);
bzero(test, 301);
bool loop = false;
int recvdBytes = 0;

strcpy(outbuf, "Enter your username: \n");
write(connFd, outbuf, strlen(outbuf));
bzero(outbuf, 301);

read(connFd, test, 300);
string uname(test);

strcpy(outbuf, "You are logged in\n");
write(connFd, outbuf, strlen(outbuf));
bzero(outbuf, 301);

while(!loop)
{
bzero(test, 301);

read(connFd, test, 300);

string tester (test);
cout << tester << endl;

if(tester == "exit")
break;

for (int i=0; i<10; ++i)
{
strcpy(outbuf, "In response to your command");
write(connFd, outbuf, strlen(outbuf));
bzero(outbuf, 301);
}
}
cout << "\nClosing thread and conn" << endl;
close(connFd);
}

客户端.cpp

# include <string.h>
# include <cstring>
# include <unistd.h>
# include <stdio.h>
# include <netdb.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <iostream>
# include <fstream>
# include <sstream>
# include <iomanip>
# include <strings.h>
# include <stdlib.h>
# include <string>
# include <time.h>
# include <vector>

using namespace std;

int main (int argc, char* argv[])
{
int sockFd, portNo;
bool loop = false;
struct sockaddr_in svrAdd;
struct hostent *server;
char inbuf[300];
int recvdBytes=0;

if(argc < 3)
{
cerr << "Syntax : ./client <host name> <port>"<<endl;
return 0;
}

portNo = atoi(argv[2]);

if((portNo > 65535) || (portNo < 2000))
{
cerr << "Please enter port number between 2000 - 65535"<<endl;
return 0;
}

//create client skt
sockFd = socket(AF_INET, SOCK_STREAM, 0);

if(sockFd < 0)
{
cerr << "Cannot open socket" << endl;
return 0;
}

server = gethostbyname(argv[1]);

if(server == NULL)
{
cerr << "Host does not exist" << endl;
return 0;
}

bzero((char *) &svrAdd, sizeof(svrAdd));
svrAdd.sin_family = AF_INET;

bcopy((char *) server -> h_addr, (char *) &svrAdd.sin_addr.s_addr, server -> h_length);

svrAdd.sin_port = htons(portNo);

int checker = connect(sockFd,(struct sockaddr *) &svrAdd, sizeof(svrAdd));

if (checker < 0)
{
cerr << "Cannot connect!" << endl;
return 0;
}

recvdBytes = read(sockFd, inbuf, 300);
cout << inbuf;
bzero(inbuf, 300);

cin >> inbuf;
write(sockFd, inbuf, strlen(inbuf)); // sending my user name to server
bzero(inbuf, 300);

read(sockFd, inbuf, 300); // recieving the message from server
cout << inbuf;
bzero(inbuf, 300);


// send commands to server
for(;;)
{

char s[300];
//cin.clear();
//cin.ignore(256, '\n');
cout << "Enter command: ";
bzero(s, 301);
cin.getline(s, 300);

write(sockFd, s, strlen(s));

// recieve data in response to your command
while(read(sockFd, inbuf, 300))
{
if(strcmp(inbuf, "done") == 0) // display the output
break;
cout << inbuf;
bzero(inbuf, 300);
}
}
}

最佳答案

常见问题。

  • connFD 不应该是静态的。它应该是 main()task1() 中的局部变量,并且应该以某种方式与启动的线程通信。否则下一个客户会破坏它并破坏第一个客户。
  • 您没有对 listen() 进行错误测试。
  • 您到处都忽略了 read() 的结果。您必须将它存储到一个变量中并检查它是否为 -1、零或正值:只有在正值的情况下循环才能继续;并且应该使用正值来限制您认为已收到的缓冲区中的字节数。
  • 你到处都忽略了 write() 的结果。

所以目前没有证据表明任何人向任何地方发送过任何东西。

关于c++:简单的TCP服务器不接受来自客户端的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34814965/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com