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

时间:2016-01-15 15:55:00

标签: c++ tcp

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

server.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);
}

client.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);      
        }
    }
}

1 个答案:

答案 0 :(得分:1)

常见问题。

  • connFD不应该是静态的。它应该是main()task1()中的局部变量,并且应该以某种方式传递给已启动的线程。否则,下一个客户端将破坏它并打破第一个客户端。
  • 您不是错误测试listen()
  • 您无视任何地方read()的结果。您必须将其存储到变量中并检查它是否为-1,零或正值:仅在正数情况下应该循环继续;并且正值应该用于限制您认为已经收到的缓冲区中的字节数。
  • 您无视任何地方write()的结果。

所以目前没有证据表明任何人已经发送过任何东西。

相关问题