//通过"@用户名"实现单发,"->all"实现群发

//1net.h
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<netdb.h>
#include<sys/types.h>
#include<pthread.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<unistd.h>
#include<sys/wait.h>
#include <arpa/inet.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<assert.h>
#include<time.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include<sys/un.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <pthread.h>
//127.0.0.1
#define SERVPORT 44432
#define BACKLOG 10
#define MAXDATASIZE 256
#define STDIN 0
#define COUNT 5

//2Server_multiple.c

#include "net.h"

int socket_fd[COUNT];
void pthread_function(int client_fd)
{
    char message[1500];
    char buf[1024];
    int i,recvbytes;
    char name[20];
    recvbytes=recv(client_fd,name,20,0);
    name[recvbytes]=':';
    name[recvbytes]='\0';
    while(1)
    {
        if((recvbytes=recv(client_fd,buf,1024,0))==-1)
        {
            perror("recv error\n");
            exit(1);
        }
        if(recvbytes==0)
        {
            printf("%s bye!(%sLeave the chat room)\n",name,name);
            break;
        }
        
        buf[recvbytes]='\0';
        for(i=0;i<COUNT;i++)
        {
            if(socket_fd[i]==-1)
            {
                continue;
            }
            else
            {
                message[0]='\0';
                strcat(message,name);
                strcat(message,buf);
                if(send(socket_fd[i],message,strlen(message),0)==-1)
                {
                    perror("send error\n");
                    exit(1);
                }
            }
        }

}
    close(client_fd);
    for(i=0;i<COUNT;i++)
    {
        if(socket_fd[i]==client_fd)
        {
            socket_fd[i]=-1;
        }
    }
    pthread_exit(NULL);
}

int main(int argc, char* argv[])
{
    int i;
    for(i=0;i<COUNT;i++)
    {
        socket_fd[i]=-1;
    }
    pthread_t id;
    int sockfd,client_fd;
    socklen_t sin_size;
    struct sockaddr_in my_addr;
    struct sockaddr_in remote_addr;
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("socket");
        exit(1);
    }
    my_addr.sin_family=AF_INET;
    my_addr.sin_port=htons(atoi(argv[2]));
    my_addr.sin_addr.s_addr=inet_addr(argv[1]);
    bzero(&(my_addr.sin_zero),8);
    if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
    {
        perror("bind false!\n");
        exit(1);
    }
    if(listen(sockfd,BACKLOG)==-1)
        {
        perror("listen false!\n");
        exit(1);
        }
        i=0;
        while(1)
        {
            sin_size=sizeof(struct sockaddr_in);
            if((client_fd=accept(sockfd,(struct sockaddr *)&remote_addr,&sin_size))==-1)
            {
                perror("accept error!\n");
                exit(1);
            }
            while(socket_fd[i]!=-1)
            {
                i=(i+1)%COUNT;
            }
            socket_fd[i]=client_fd;
            pthread_create(&id,NULL,(void *)pthread_function,(int *)(long)client_fd);//(int *)client_fd,修改成(int *)(long)client_fd(形参int* 是 8 字节,而实参 int client_fd却是 4 字节。为了避免这个警告变为long int 型)
        }
}

//3Client_multiple.c

#include "net.h"

char recv_buf[1500],send_buf[1024];
char name[20];
void pthread_function(int sockfd)
{
    int recvbytes;
    while(1)
    {
        if((recvbytes=recv(sockfd,recv_buf,1500,0))==-1)
        {
            perror("recv error\n");
            exit(1);
        }
        else
        {
            recv_buf[recvbytes]='\0';
            char *x,*y;
            x=strstr(recv_buf,"@");
            y=strstr(recv_buf,"->all");
            int flag=1;
            if(x!=NULL)
            {
                x=strcat(x,":");
                flag=strcmp(x+1,name);
                if(!flag)
                {
                    recv_buf[recvbytes]='\0';
                    printf("%s\n",recv_buf);
                }
                    
            }
            else if(y!=NULL)
            {
                flag=strcmp(y,"->all");
                recv_buf[recvbytes-5]='\0';
                printf("%s\n",recv_buf);
            }
            else;
        }
    }
}

int main(int argc, char* argv[])
{
    pthread_t id;
    int sockfd;
    struct sockaddr_in server_addr;
    server_addr.sin_family=AF_INET;
    server_addr.sin_port=htons(atoi(argv[2]));
    server_addr.sin_addr.s_addr=inet_addr(argv[1]);//127.0.0.1
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
    {
        perror("socket error\n");
        exit(1);
    }
    if(connect(sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
    {
        perror("connect error\n");
        exit(1);
    }

printf("input your name:");
    scanf("%s",name);
    strcat(name,":");
    send(sockfd,name,strlen(name),0);
    pthread_create(&id,NULL,(void *)pthread_function,(int *)(long)sockfd);//(int *)client_fd,修改成(int *)(long)client_fd(形参int* 是 8 字节,而实参 int client_fd却是 4 字节。为了避免这个警告变为long int 型)
    while(1)
    {
        gets(send_buf);
        if(send(sockfd,send_buf,strlen(send_buf),0)==-1)
        {
            perror("send error\n");
            exit(1);
        }
        sleep(1);
    }
    close(sockfd);
    pthread_cancel(id);
    return 0;    
}

参考Linux程序设计第三版(金..)

基于LInuxc语言TCP聊天服务端程序实现私聊,以及群聊和私聊的转换相关推荐

  1. 易语言tcp多线程服务端客户端_从TCP协议到TCP通信的各种异常现象和分析

    很多人总觉得学习TCP/IP协议没什么用,觉得日常编程开发只需要知道socket接口怎么用就可以了.如果大家定位过线上问题就会知道,实际上并非如此.如果应用在局域网内,且设备一切正常的情况下可能确实如 ...

  2. TCP多人聊天程序Java实现(群聊,私聊,在线用户,踢出用户)

    本程序在程序 https://blog.csdn.net/joffy/article/details/18079331 的基础是上添加了私聊,踢出用户两个功能. 由客户端和服务器端构成程序,程序借助J ...

  3. linux写聊天程序,轻易实现基于linux或win运行的聊天服务端程序

    对于不了解网络编程的开发人员来说,编写一个良好的服务端通讯程序是一件比较麻烦的事情.然而通过EC这个免费组件你可以非常简单地构建一个基于linux或win部署运行的网络服务程序.这种便利性完全得益于m ...

  4. 易语言tcp多线程服务端客户端_太详细了,TCP协议面试灵魂10问,建议收藏!

    推荐阅读: 阿里P9架构师120分钟带你掌握线程池,不在为线程而烦恼​www.bilibili.com 不懂算法怎么去字节等大厂面试?左程云大神联合马士兵大佬120分钟带你掌握算法底层​www.bil ...

  5. TCP/IP网络编程之基于TCP的服务端/客户端(一)

    TCP/IP网络编程之基于TCP的服务端/客户端(一) 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字.因为TCP套接字是面向连接的,因此又称为基于 ...

  6. TCP/IP网络编程之基于TCP的服务端/客户端(二)

    回声客户端问题 上一章TCP/IP网络编程之基于TCP的服务端/客户端(一)中,我们解释了回声客户端所存在的问题,那么单单是客户端的问题,服务端没有任何问题?是的,服务端没有问题,现在先让我们回顾下服 ...

  7. OSI七层模型以及TCP/UDP客户端/服务端程序实例

    OSI七层模型以及TCP/UDP客户端/服务端程序实例 一.前言 二.OSI简介 2.1 OSI概念 2.2 划分原则 2.3 OSI七层模型 2.4 模型举例 三.Linux下TCP/UDP程序开发 ...

  8. TCP服务端程序开发

    TCP服务端程序开发 1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象 绑定端口号 设置监听 等待接受客户端的连接请求 接收数据 发送数据 关闭套接字 2. socket 类的介绍 ...

  9. 网络编程之TCP服务端程序开发

    TCP服务端程序开发 学习目标 能够写出TCP服务端应用程序接收和发送消息 1. 开发 TCP 服务端程序开发步骤回顾 创建服务端端套接字对象 绑定端口号 设置监听 等待接受客户端的连接请求 接收数据 ...

  10. 基于半同步/半反应堆线程池实现的HTTP解析服务端程序

    简介: 半同步/半反应堆线程池是通过一个线程往工作队列添加任务T,然后工作线程竞争工作队列获得任务T.HTTP请求解析服务端程序:逐行解析客户端发送来的HTTP请求然后作出HTTP回答.采用线程池就是 ...

最新文章

  1. linux与windows回车换行符的区别
  2. 你所需要的java基础篇深入解析大汇总
  3. 经典C语言程序100例之三六
  4. Xcode12.5最新快捷键的使用(学会事半功倍)
  5. ThinkPHP分页链接支持数组参数的办法
  6. find()matlab,Matlab 之 find()函数
  7. 今天rpm装glibc和glibc-common版本,出现二个包相互依赖,解决办法
  8. Elasticsearch优化的一些建议
  9. vscode web版,走到哪用到哪
  10. 软件测试面试两分钟自我介绍
  11. 趋势科技4月移动客户端病毒报告
  12. 如何伪装成一个服务端开发(五)
  13. 玫瑰花怎么画?花朵怎么画?鲜花怎么画?
  14. 软件测试用例设计之Pairwise算法
  15. 滴水中级线上班完整版
  16. jquery中的$()是什么
  17. 他被称为中国第一程序员,一人之力单挑微软,如今拜入武当修道(转载)
  18. 【洛谷P2947】向右看齐
  19. 台式计算机一般多大功率,电脑的功率有多大,台式电脑的功率是多少
  20. set_input_delay如何使用?

热门文章

  1. 怎样快速做个 BI 系统
  2. 数据库可视化软件 安装 for windows
  3. 双主动桥隔离双向DC-DC变换器(三) 控制策略
  4. ZBrush建模的15个小技巧,萌新小白都用得上的干货,速看
  5. 学习C语言编程,推荐你看这6本书
  6. 通俗易懂的自动控制原理 # 绪论
  7. 微软雅黑的问题(for silverlight)
  8. 《简明python教程》沈洁元
  9. mtk x20 android 开发环境配置
  10. dojo实现省份地市级联报错(一)