套接字编程简单聊天C ++

时间:2016-01-26 17:11:40

标签: c++ sockets chat

我正在尝试使用套接字编程实现一个简单的聊天,其中'enter'键将响应发送到客户端到服务器,反之亦然。下面的代码按预期工作,特殊字符如'*'作为缓冲区,但当我尝试使用'\ n'时,消息永远不会被发送。我必须错误地实现'enter'部分。关于如何解决这个问题的任何想法?

服务器:

#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>

using namespace std;

int main()
{

    int client, server;
    int portNum = 1500;
    bool isExit = false;
    int bufsize = 1024;
    char buffer[bufsize];

    struct sockaddr_in server_addr;
    socklen_t size;

    client = socket(AF_INET, SOCK_STREAM, 0);

    if (client < 0)
    {
        cout << "\nError establishing socket..." << endl;
        exit(1);
    }

    cout << "\n=> Socket server has been created..." << endl;

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(portNum);


    if ((bind(client, (struct sockaddr*)&server_addr,sizeof(server_addr))) < 0)
    {
        cout << "=> Error binding connection, the socket has already been established..." << endl;
        return -1;
    }


    size = sizeof(server_addr);
    cout << "=> Looking for clients..." << endl;

    listen(client, 1);


    int clientCount = 1;
    server = accept(client,(struct sockaddr *)&server_addr,&size);

    // first check if it is valid or not
    if (server < 0)
        cout << "=> Error on accepting..." << endl;

    while (server > 0)
    {
        strcpy(buffer, "=> Server connected...\n");
        send(server, buffer, bufsize, 0);
        cout << "=> Connected with the client #" << clientCount << ", you are good to go..." << endl;
        cout << "\n=> Enter # to end the connection\n" << endl;

        cout << "Client: ";
        do {
            recv(server, buffer, bufsize, 0);
            cout << buffer << " ";
            if (*buffer == '#') {
                *buffer = '\n';
                isExit = true;
            }
        } while (*buffer != '\n');

        do {
            cout << "\nServer: ";
            do {
                cin >> buffer;
                send(server, buffer, bufsize, 0);
                if (*buffer == '#') {
                    send(server, buffer, bufsize, 0);
                    *buffer = '\n';
                    isExit = true;
                }
            } while (*buffer != '\n');

            cout << "Client: ";
            do {
                recv(server, buffer, bufsize, 0);
                cout << buffer << " ";
                if (*buffer == '#') {
                    *buffer = '\n';
                    isExit = true;
                }
            } while (*buffer != '\n');
        } while (!isExit);

        cout << "\n\n=> Connection terminated with IP " << inet_ntoa(server_addr.sin_addr);
        close(server);
        cout << "\nGoodbye..." << endl;
        isExit = false;
        exit(1);
    }

    close(client);
    return 0;
}

客户端:

#include <iostream>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>

using namespace std;

int main()
{

    int client;
    int portNum = 1500; // NOTE that the port number is same for both client and server
    bool isExit = false;
    int bufsize = 1024;
    char buffer[bufsize];
    char* ip = "192.168.0.8";

    struct sockaddr_in server_addr;

    client = socket(AF_INET, SOCK_STREAM, 0);

    if (client < 0)
    {
        cout << "\nError establishing socket..." << endl;
        exit(1);
    }


    cout << "\n=> Socket client has been created..." << endl;

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(portNum);

    if (connect(client,(struct sockaddr *)&server_addr, sizeof(server_addr)) == 0)
        cout << "=> Connection to the server port number: " << portNum << endl;


    cout << "=> Awaiting confirmation from the server..." << endl; //line 40
    recv(client, buffer, bufsize, 0);
    cout << "=> Connection confirmed, you are good to go...";

    cout << "\n\n=> Enter # to end the connection\n" << endl;

    do {
        cout << "Client: ";
        do {
            cin >> buffer;
            send(client, buffer, bufsize, 0);
            if (*buffer == '#') {
                send(client, buffer, bufsize, 0);
                *buffer = '\n';
                isExit = true;
            }
        } while (*buffer != '\n');

        cout << "Server: ";
        do {
            recv(client, buffer, bufsize, 0);
            cout << buffer << " ";
            if (*buffer == '#') {
                *buffer = '\n';
                isExit = true;
            }

        } while (*buffer != '\n');
        cout << endl;

    } while (!isExit);

    cout << "\n=> Connection terminated.\nGoodbye...\n";

    close(client);
    return 0;
}

编辑:我在下面的答案中引用了更改,但我仍然没有得到预期的结果。

以下是运行服务器和客户端时发生的情况: enter image description here

当我按Enter键时,消息未被发送到服务器。但是,当我使用“buffer ='*'”运行相同的代码时,它按预期工作。

3 个答案:

答案 0 :(得分:2)

我不确定您的代码应该做什么。

*buffer == '\n';

这是你的错误吗?

它位于服务器代码中:

        cout << "Client: ";
        do {
            recv(server, buffer, bufsize, 0);
            cout << buffer << " ";
            if (*buffer == '#') {
                *buffer == '\n';
                isExit = true;
            }
        } while (*buffer != '\n');

我想你打算写:

        cout << "Client: ";
        do {
            recv(server, buffer, bufsize, 0);
            cout << buffer << " ";
            if (*buffer == '#') {
                *buffer = '\n';
                isExit = true;
            }
        } while (*buffer != '\n');

看一下测试驱动开发的主题。

答案 1 :(得分:1)

@ Johannes已经确定了可能的错误(一个非常常见的错误!),这是您正在目睹的行为的罪魁祸首,但您肯定需要倾听您的编译器。当我使用clang(CentOS 6上的3.4.2)编译你的服务器源并启用所有警告时,我得到以下输出:

$ clang -Wall -lstdc ++ server.cpp

server.cpp:93:29: warning: equality comparison result unused [-Wunused-comparison]
                    *buffer == '\n';
                    ~~~~~~~~^~~~~~~
server.cpp:93:29: note: use '=' to turn this equality comparison into an assignment
                    *buffer == '\n';
                            ^~
                            =
1 warning generated.

$ clang -Wall -lstdc ++ client.cpp

client.cpp:21:16: warning: conversion from string literal to 'char *' is deprecated [-Wc++11-compat-deprecated-writable-strings]
    char* ip = "192.168.0.8";
               ^
client.cpp:21:11: warning: unused variable 'ip' [-Wunused-variable]
    char* ip = "192.168.0.8";
          ^
2 warnings generated.

您还可以使用任意数量的静态分析工具(快速搜索让我this wiki)以最小的努力提高您的代码质量。

答案 2 :(得分:-1)

if(inet_pton(AF_INET, "server_ip", &server_addr.sin_addr)<=0)  
    { 
        cout<<"Invalid address/ Address not supported"<<endl;
        return -1; 
    }