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

 

//通过"@用户名"实现单发,"->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程序设计第三版(金..)
 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值