利用soket 创建已经简单的聊天室程序

#include
#include
#include
#include
#include
#include
#include
#include
#include

#define SERVER_PORT 8888
typedef struct
{
    int c_fd;
    char ip[16];

}clinet;
#define MAX_CLINET 100
clinet g_clinet[MAX_CLINET];
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;

void broadcast(int fd, void * msg, int len)
{
    write(STDOUT_FILENO, msg , len);
    pthread_mutex_lock(&m);
    int i =0;
    for(;i < MAX_CLINET; i++)
    {
        if(g_clinet[i].c_fd != 0 && g_clinet[i].c_fd != fd)
        {
            write(g_clinet[i].c_fd, msg, len);
        }
    }
    pthread_mutex_unlock(&m);
}
void * func(void *arg)
{
    clinet *parg = arg;
    char ip[16] = {0};
    pthread_mutex_lock(&m);
    int c_fd = parg->c_fd;
    strncpy(ip, parg->ip, sizeof(ip));    
    pthread_mutex_unlock(&m);
    char msg[1024];
    int n = sprintf(msg, "Welcome %s join us\n", ip);
    int ip_len = sprintf(msg, " %s said: ", ip);
    broadcast(0 ,msg , n); //对所有客户端广播
    for(;;)
    {
        int len = read(c_fd, msg+ip_len, sizeof(msg) - ip_len);
        if(len < 0)
            break;
        if(msg[ip_len] == 'q' && isspace(msg[ip_len+1]))
            break;
        broadcast(c_fd ,msg , len+ip_len); //对所有客户端广播
    }
    close(c_fd);
    pthread_mutex_lock(&m);
    parg->c_fd = 0;
    pthread_mutex_unlock(&m);
    
    n = sprintf(msg, "%s leaved\n", ip);
    broadcast(0 ,msg , n); //对所有客户端广播
}   


int main(int argc,char* argv[])
{
    int s_fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in si;
    memset(&si, 0 , sizeof(si));
    si.sin_family = AF_INET;
    si.sin_addr.s_addr = htonl(INADDR_ANY);
    si.sin_port = htons(SERVER_PORT);
    if(bind(s_fd, (struct sockaddr *)&si, sizeof(si)) < 0)
    {
        perror("bind failed.\n");
        return -1;
    }

    listen(s_fd, 10);
    for(;;)
    {
        socklen_t len = sizeof(si);
        int c_fd = accept(s_fd, (struct sockaddr *)&si, &len);
        if(c_fd < 0)
        { 
            continue;
        }
        int i = 0;
        pthread_mutex_lock(&m);
        for(i = 0; i < MAX_CLINET && g_clinet[i].c_fd != 0; i++){}
        if(i == MAX_CLINET)
        {
            write(c_fd, "full!\n",6);
            close(c_fd);
        }
        else
        {
            g_clinet[i].c_fd = c_fd;
            inet_ntop(AF_INET, &si.sin_addr, g_clinet[i].ip, sizeof(g_clinet[i].ip));
            pthread_t id;
            pthread_create(&id, NULL , func, &g_clinet[i]);
        }
        
        pthread_mutex_unlock(&m);
    }
}

 

你可能感兴趣的:(网络编程)