c++编写聊天室服务端(Liunx)

  • C++:使用C++语言进行编程,包括使用C++标准库和相关的数据类型、函数等。
  • Socket编程:基于套接字(Socket)的网络通信,通过创建套接字、绑定地址、监听连接请求、接受客户端连接等操作来建立服务器端。
  • Linux环境:在Linux操作系统下进行开发,使用相应的系统调用和头文件。
  • 网络协议:基于TCP/IP协议栈进行通信,使用TCP协议实现可靠的数据传输

实际的网络编程可能还涉及其他高级技术和功能,例如多线程处理、非阻塞IO、异步编程、网络安全等,具体根据需求进行扩展和优化。

 编写思路

  • 导入所需的头文件:
  • #include <iostream>
    #include <sys/socket.h>
    #include <netinet/in.h>//网络通信TCP/IP协议
    #include <unistd.h>
    
  • 创建套接字:

  • int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        std::cout << "Failed to create socket" << std::endl;
        return -1;
    }
    
  • 设置服务器地址和端口:

  • sockaddr_in serverAddress{};
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_addr.s_addr = INADDR_ANY;
    serverAddress.sin_port = htons(port); // 设置端口号
    
    if (bind(sockfd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) {
        std::cout << "Binding failed" << std::endl;
        return -1;
    }
    
  • 监听连接请求:

  • if (listen(sockfd, backlog) < 0) {
        std::cout << "Listening failed" << std::endl;
        return -1;
    }
    
  • 接受客户端连接:

  • sockaddr_in clientAddress{};
    socklen_t clientAddressLength = sizeof(clientAddress);
    
    int clientSocket = accept(sockfd, (struct sockaddr*)&clientAddress, &clientAddressLength);
    if (clientSocket < 0) {
        std::cout << "Accepting connection failed" << std::endl;
        return -1;
    }
    
  • 和客户端进行通信: 在这一步可以根据具体需求编写代码来处理和客户端之间的通信。可以使用clientSocket来发送和接收数据。

  • 关闭套接字:

    close(clientSocket);
    close(sockfd);
    

 请注意,在Linux环境下,可能还需要添加适当的权限和设置防火墙规则,以确保网络连接正常

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <list>
using namespace std;

#define _PORT_ 2022
#define _BACKLOG_ 10

// 客服连接到服务器后,需要先登录,发送登录消息:
// name字符串,不能含有空格

struct client {
public:
        int socket;
        char name[32];
        char ip[16];

        bool operator==(const client &other) const {
                return other.socket == socket;
        }
};

list<client> clients;

void showClients() {
        printf("\n\n***********show all clients********\n");
        int k=0;
        for(auto it=clients.begin(); it != clients.end(); it++) {
                printf("NO.%d name:[%s] socket:[%d]\n", ++k, it->name, it->socket);
        }
        printf("\n*********************************** \n\n");
}

void* client_func(void *arg) {
        client *p = (client*)arg;

        // regist
        char buf[1024];
        char buff2[1024];
        memset(buf,'0',sizeof(buf));//跟前面的初始化对比
        if (read(p->socket, buf, sizeof(buf)) <= 0) {
                delete  p;
                return NULL;
        }

        printf("Receive register info: %s\n",buf);
        sscanf(buf, "%s", p->name);
        sprintf(buf, "【%s@%s】进入聊天室", p->ip, p->name);

        clients.push_back(*p);
        printf("Add a new client. count=%d\n", clients.size());
        //showClients();

        printf("clients size = %d\n", clients.size());
        int k=0;

        for(auto it=clients.begin(); it != clients.end(); it++) {
                printf("send no.%d client\n", ++k);
                write(it->socket, buf, strlen(buf)+1);
        }

        //clients.push_back(*p);

        while(1) {
                int ret = read(p->socket, buf, sizeof(buf));
                if (ret <= 0) {
                        break;
                }
                printf("client :# %s\n",buf);

                sprintf(buff2, "【%s@%s】%s", p->ip, p->name, buf);

                for(auto it=clients.begin(); it != clients.end(); it++) {
                        if (it->socket != p->socket) {
                                write(it->socket, buff2, strlen(buff2)+1);
                        }
                }
    }

        clients.remove(*p);
        delete p;
        return NULL;
}


int main()
{
    int sock = socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in server_socket;
    struct sockaddr_in client_socket;
    bzero(&server_socket,sizeof(server_socket));
    server_socket.sin_family = AF_INET;
    server_socket.sin_port = htons(_PORT_);
    server_socket.sin_addr.s_addr = htonl(INADDR_ANY);

    bind(sock,(struct sockaddr *)&server_socket,sizeof(struct sockaddr_in));
    listen(sock,_BACKLOG_);

    while(1) {
        socklen_t len = sizeof(client_socket);
        printf("wait accept...\n");
        int client_sock = accept(sock,(struct sockaddr *)&client_socket,&len);
        if(client_sock < 0) {
            printf("accept error, error is %d,errstring is %s\n",errno,strerror(errno));
            close(sock);
            return 3;
        }

        client *c = new client;
        strcpy(c->ip, inet_ntoa(client_socket.sin_addr));
        printf("get connect,ip is %s\n", c->ip);
        c->socket = client_sock;


        pthread_t tid;
        pthread_create(&tid, NULL, client_func, (void*)c);
    }
    close(sock);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_72703340/article/details/131606808
今日推荐