【C语言】实现简易网络聊天室

项目:

制作一个简易的聊天室,实现实时非单机聊天

知识点:

总体框架:

【C语言】实现简易网络聊天室_第1张图片

【C语言】实现简易网络聊天室_第2张图片

socket() 创造套接字函数:

【C语言】实现简易网络聊天室_第3张图片

然后设置 bind() ,调整 IP 参数:

【C语言】实现简易网络聊天室_第4张图片

【C语言】实现简易网络聊天室_第5张图片

【C语言】实现简易网络聊天室_第6张图片

然后设置 listen() : 

【C语言】实现简易网络聊天室_第7张图片

 然后设置 accept() :

【C语言】实现简易网络聊天室_第8张图片

收发数据 recv(), send()/sendto(), read(), write() :

最后关闭 close() :

因为本身 socket 是一种文件描述符,所以最后要关闭打开的文件

 服务端:

1.创建sd

    //创建sd
    sd = socket(AF_INET,SOCK_STREAM,0);
    if(sd == -1)
    {
        perror("create sd failed");
        return -1;
    }

2.配置ip,端口属性

//设置ip,端口
    server_ip.sin_family = AF_INET;
    server_ip.sin_port = htons(5678);
    server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(server_ip.sin_zero,0,8);

3.绑定ip和客户端 

    //绑定ip和客户端
    error = bind(sd,(struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
    if(error == -1)
    {
        perror("create bind failed");
        close(sd);
        return -1;
    }

4.设置最大链接数,这个宏定义MAX_LISLEN=2,因为我这里只连接2个客户端,可以设置多个

//设置最大链接数
    error = listen(sd, MAX_LISLEN);
    if(error == -1)
    {
        perror("create listem failed");
        close(sd);
        return -1;
    }

 5.等待客户端连接

 ad[i] = accept(sd,(struct sockaddr *)(&remote_ip),&remote_len);
        if(ad[i] == -1)
        {
            perror("create ad failed");
            close(sd);
            return -1;
        }  

6.创造新线程,不断读取客户端发送的数据,别写入另外一个客户端

void * pthread_fun(void * arg)
{
    while(1)
    {
        memset(buf,0,100);
        read(ad[(int )arg],buf,100);
        write(ad[((int )arg + 1) % 2],buf,100);
    }
    return (void *) 0;
}

客户端 :

 1.创建sd

    //创建sd
    sd = socket(AF_INET,SOCK_STREAM,0);
    if(sd == -1)
    {
        perror("create sd failed");
        return -1;
    }

2.配置ip,端口属性

//设置ip,端口
    server_ip.sin_family = AF_INET;
    server_ip.sin_port = htons(5678);
    server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(server_ip.sin_zero,0,8);

3.连接服务端

//链接服务端
    error = connect(sd, (struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
    if(error == -1)
    {
        perror("create connect failed");
        close(sd);
        return -1;
    }

 4.创建两个新线程,不断写数据个服务端,不断从服务端读数据

void * pthread_fun_write(void * arg)
{
    while(1)
    {
        memset(buf_write,0,100);
        scanf("%s",buf_write);
        write(sd,buf_write,100);
    }
}
void * pthread_fun_read(void * arg)
{
    while(1)
    {
        memset(buf_read,0,100);
        read(sd,buf_read,100);
        printf("client2:%s\n",buf_read);
    }
}

附录 

服务端代码

#include
#include
#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 
#define MAX_LISLEN 2
char buf_write[100];
char buf[100];
int ad[2];
struct sockaddr_in server_ip, remote_ip;
void * pthread_fun(void * arg)
{
    while(1)
    {
        memset(buf,0,100);
        read(ad[(int )arg],buf,100);
        write(ad[((int )arg + 1) % 2],buf,100);
    }
    return (void *) 0;
}

int main()
{
    pthread_t tid[2];
    int server_len , remote_len;
    int error, sd ;
    int i = 0;
    //创建sd
    sd = socket(AF_INET, SOCK_STREAM ,0);
    if(sd == -1)
    {
        perror("create sd failed");
        return -1;
        //close(sd);
    }
    //设置ip,端口
    server_ip.sin_family = AF_INET;
    server_ip.sin_port = htons(5678);
    server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(server_ip.sin_zero,0,8);
    //绑定ip和客户端
    error = bind(sd,(struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
    if(error == -1)
    {
        perror("create bind failed");
        close(sd);
        return -1;
    }
    //设置最大链接数
    error = listen(sd, MAX_LISLEN);
    if(error == -1)
    {
        perror("create listem failed");
        close(sd);
        return -1;
    }
    remote_len = sizeof(struct sockaddr);
    while(1)
    {
        //等待客户端申请
        ad[i] = accept(sd,(struct sockaddr *)(&remote_ip),&remote_len);
        if(ad[i] == -1)
        {
            perror("create ad failed");
            close(sd);
            return -1;
        }  
        else
        {
            printf("client%d 加入聊天室\n",i+1);
        } 
        //新线程,功能:不断读数据
        error = pthread_create(&tid[i],NULL,pthread_fun,(void*) i);
        if(error != 0)
        {
            perror("create pthread_fun  failed");
            close(ad[i]);
            close(sd);
            return -1;
        } 
        i++;
    }
    close(sd);
    return 0;

}

客户端1代码 

#include
#include
#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 
int sd;
char buf_write[100];
char buf_read[100];
struct sockaddr_in server_ip, remote_ip;
void * pthread_fun_write(void * arg)
{
    while(1)
    {
        memset(buf_write,0,100);
        scanf("%s",buf_write);
        write(sd,buf_write,100);
    }
}
void * pthread_fun_read(void * arg)
{
    while(1)
    {
        memset(buf_read,0,100);
        read(sd,buf_read,100);
        printf("client2:%s\n",buf_read);
    }
}

int main()
{
    int server_len,remote_len;
    pthread_t tid_read,tid_write;
    int error;
    sd = socket(AF_INET,SOCK_STREAM,0);
    if(sd == -1)
    {
        perror("create sd failed");
        return -1;
    }

    //设置ip,端口
    server_ip.sin_family = AF_INET;
    server_ip.sin_port = htons(5678);
    server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(server_ip.sin_zero,0,8);
    //链接服务端
    error = connect(sd, (struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
    if(error == -1)
    {
        perror("create connect failed");
        close(sd);
        return -1;
    }
    error = pthread_create(&tid_write,NULL,pthread_fun_write,NULL);
    if(error != 0)
    {
        perror("create pthread write failed");
        close(sd);
        return -1;
    } 
    error = pthread_create(&tid_read,NULL,pthread_fun_read,NULL);
    if(error != 0)
    {
        perror("create pthread read failed");
        close(sd);
        return -1;
    } 
    pthread_join(tid_write,NULL);
    pthread_join(tid_read,NULL);
    return 0;
}

客户端2代码 

#include
#include
#include           /* See NOTES */
#include 
#include 
#include 
#include 
#include 
#include 
int sd;
char buf_write[100];
char buf_read[100];
struct sockaddr_in server_ip, remote_ip;
void * pthread_fun_write(void * arg)
{
    while(1)
    {
        memset(buf_write,0,100);
        scanf("%s",buf_write);
        write(sd,buf_write,100);
    }
}
void * pthread_fun_read(void * arg)
{
    while(1)
    {
        memset(buf_read,0,100);
        read(sd,buf_read,100);
        printf("client1:%s\n",buf_read);
    }
}

int main()
{
    int server_len,remote_len;
    pthread_t tid_read,tid_write;
    int error;
    sd = socket(AF_INET,SOCK_STREAM,0);
    if(sd == -1)
    {
        perror("create sd failed");
        return -1;
    }

    //设置ip,端口
    server_ip.sin_family = AF_INET;
    server_ip.sin_port = htons(5678);
    server_ip.sin_addr.s_addr = htonl(INADDR_ANY);
    memset(server_ip.sin_zero,0,8);
    error = connect(sd, (struct sockaddr *) (&server_ip),sizeof(struct sockaddr));
    if(error == -1)
    {
        perror("create connect failed");
        close(sd);
        return -1;
    }
    error = pthread_create(&tid_write,NULL,pthread_fun_write,NULL);
    if(error != 0)
    {
        perror("create pthread write failed");
        close(sd);
        return -1;
    } 
    error = pthread_create(&tid_read,NULL,pthread_fun_read,NULL);
    if(error != 0)
    {
        perror("create pthread read failed");
        close(sd);
        return -1;
    } 
    pthread_join(tid_write,NULL);
    pthread_join(tid_read,NULL);
    return 0;
}

写运行服务端创建sd,再运行客户端连接服务端,再不断加入客户端,注意最大加入数

运行结果:

想得美,直接动手

你可能感兴趣的:(Linux系统编程,网络,p2p)