C ++中的TCP / IP服务器不等待客户端

时间:2015-12-30 00:41:29

标签: c++ sockets tcp qt-creator

我在互联网上找到了一些关于在C ++中创建TCP / IP服务器的基础知识。 我拿了这段代码,添加了一些库和一些代码行。结果是,我能够在Windows上的Qt Creator中编译和运行代码/服务器作为控制台程序。然而,我无法连接到服务器,因为它只是运行代码而无需等待并接受来自TCP客户端的连接。

这是代码: 编辑:代码已更新,现在正在运行。测试== -1是解决方案。

#define PORT 2000
#define MAX_QUEUE 5
#define BUF_SIZE 1024

int main(int argc, char* const argv[])
{
cout << "Hello World!" << endl;    
        WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
cout << "wsaret: " << wsaret << endl;

cout << "Start TCP/IP Server" << endl;

/* file descriptors for sockets */
SOCKET sock_1, sock_2;  //switched from in to SOCKET //unsigned int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];

//struct sockaddr_in server;
struct sockaddr_in server;

/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//if(sock_1 < 0)
if(sock_1 == -1)
{
    cout << "socket: " << WSAGetLastError() << endl; //instead of //cout << "socket: " << strerror(errno) << endl; //cout << "socket wsaret: " << wsaret << endl;
    exit(1);
}

/* build address in internet domain */
server.sin_family = AF_INET;

/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = htons(2000);  //server.sin_port = PORT; //Port: 2000

/* bind socket */
//if(bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
int bindreturn = (bind(sock_1, (struct sockaddr *)&server, sizeof(server)));
if(bindreturn == -1)
{
    cout << "bind: " << WSAGetLastError() << endl; //instead of //cout << "bind: " << strerror(errno) << endl; //cout << "bind wsaret: " << wsaret << endl;
    exit(1);
}

listen(sock_1,MAX_QUEUE);
    /* start accepting connection */
    sock_2 = accept(sock_1,0,0);
    if(sock_2 < 0)
    {
        cout << "accept: " << WSAGetLastError() << endl;
        exit(1);
    }

    /* read from sock_2 */
    while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
    {
        if(rec_value < 0)

        {
         cout << "recv: " << WSAGetLastError() << endl;
         exit(1);
        }
        else
        {
            cout << "else" << endl;
            send(sock_2,"1,2,3",strlen("1,2,3"),0);
        }
    }

    cout << "Ending connection" << endl;
    closesocket(sock_1);
    closesocket(sock_2);
    cout << "End TCP/IP Server" << endl;

    WSACleanup();
return 0;
}

控制台在一秒或几秒钟内运行程序后显示以下内容:

Hello World!
wsaret: 0
Start TCP/IP Server
bind: 0

我该怎么做,服务器等待连接伙伴?

提前致谢。

此致 MATL

编辑:在开头添加了几行代码,我以前忘了。 编辑:代码更新 编辑:代码更新

2 个答案:

答案 0 :(得分:3)

我将详细评论您发布的原始代码。

cout << "Start TCP/IP Server" << endl;

//int sock_1,sock_2;     /* file descriptors for sockets */
int sock_1, sock_2;
int rec_value, length;
char buf[BUF_SIZE];

//struct sockaddr_in server;
sockaddr_in server;

/* create stream socket in internet domain*/
sock_1 = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//0);

这里缺少测试。您必须在以下行中测试结果-1:

if (sock_1 == -1)
{
    cout << "socket creation error: " << WSAGetLastError() << endl;
    exit(1); // or some other measure to prevent continuation
}

返回您的代码:

/* build address in internet domain */
server.sin_family = AF_INET;

/* everyone is allowed to connet to server */
server.sin_addr.s_addr = INADDR_ANY; //inet_addr("192.168.145.129");
server.sin_port = PORT; //Port: 2000

那应该是

server.sin_port = htons(PORT);

返回您的代码:

/* bind socket */
int bindreturn = bind(sock_1, (struct sockaddr *)&server, sizeof(server));
cout << "bindreturn: " << bindreturn << endl;

不足。在这里,你需要再次测试-1,然后打印WSAGetLastError()并在你得到它时退出。

listen(sock_1,MAX_QUEUE);

未测试。在这里你需要测试-1等。

    /* start accepting connection */
    //system("pause");
    sock_2 =accept(sock_1,0,0);
    //system("pause");
    cout << "acceptreturn: " << sock_2 << endl;

再次不足,见上文。

    /* read from sock_2 */
    while(rec_value=recv(sock_2,buf,BUF_SIZE,0))
    {
        if(rec_value<0)
        {
         cout << "error: " << rec_value << endl;
         exit(1);
        }

测试不正确。系统调用通过精确返回-1来指示错误,而不仅仅是任何值&lt; 0.例如socket()accept()返回的套接字FD可以是负数,也可以是-1以外的任何值。

        else
        {
            cout << "else" << endl;
            send(sock_2,"1,2,3",strlen("1,2,3"),0);
        }
    }
closesocket(sock_1);
closesocket(sock_2);

cout << "End TCP/IP Server" << endl;

return 0;

closesocket()调用显而易见,您正在使用Winsock,在这种情况下,WSAStart()WSACleanup()都会丢失。

答案 1 :(得分:2)

如何定义PORT

您应该使用:

server.sin_port = htons(PORT); //Port: 2000

您的IP地址是否正确?

您的所有来电都在接收SOCKET_ERROR( - 1),因此您应该检查lasterror以获取更多信息。

不确定(在Windows上这里),但不应该是unsigned int&#39>?

int sock_1, sock_2;

<强>更新

好的,你似乎在Windows上使用Qt。

对于Qt,您也可以使用Qt libraries

在Windows上,您可以使用免费的MS Visual Studio。

您还需要像这样致电WSAStartup()

WSADATA wsaData;
int wsaret = WSAStartup(MAKEWORD( 4, 4 ), &wsaData);
// check wsaret

// more code here

WSACleanup();

还可以使用SOCKET

SOCKET sock_1, sock_2;

使用WSAGetLastError()检查错误代码。