Linux c语言TCP多线程聊天组程序

Linux c语言TCP多线程聊天组程序

  • 服务器端
  • 客户端

服务器端

const int PORT = 3344;
int ssocks[QLEN] ;

void recvMsg(int fd);
void broadcastMsg(int, char *,int);
int errexit(const char *format, ...);
int passiveTCP(int port, int qlen);

int main(int argc, char *argv[])
{
    pthread_t th[QLEN];
    int conncount = 0;
    int port = PORT;
    struct sockaddr_in fsin;
    unsigned int alen;
    int msock;
 
 	//接收参数
    switch (argc)
    {
    case 1:
        break;
    case 2:
        port = atoi(argv[1]);
    default:
        errexit("usage:ChatServer[port]\n");
    }

    //获取主套接字
    msock = passiveTCP(port, QLEN);

    while (1)
    {
        alen = sizeof(fsin);
        ssocks[conncount++] = accept(msock, (struct sockaddr *)&fsin, &alen);
        if (ssocks[conncount - 1] < 0)
        {
            if (errno == EINTR)
                continue;
            errexit("accept: %s\n", strerror(errno));
        }
        printf("服务器与客户端建立链接...\n\n");
        if (pthread_create(&th[conncount-1], NULL, (void *(*)(void *))recvMsg,
                           (void *)(long)ssocks[conncount - 1]) < 0) {
            printf("线程启动失败\n");
        }
    }
}

/*
*   接收客户端信息并转发
*/
void recvMsg(int fd)
{
    int cc;
    char buf[BUFSIZ + 1];
    printf("进入转发线程\n");
    //显示欢迎界面
    char str[BUFSIZE+1] =
        "-------------------------------------------------------------\n------------------------欢迎加入聊天组-----------------------\n-------------------------------------------------------------\n\n";
    str[BUFSIZE]='\0';
    printf("fd: %d\n",fd);
    if (write(fd, str, sizeof buf) < 0)
        errexit("发送欢迎界面失败!%s\n", strerror(errno));
    strcpy(str,"---有新成员加入---\n\n");
    broadcastMsg(fd, str, sizeof str);
    while (1)
    {
        memset(buf,'\0',strlen(buf));
        //接收改客户端信息并转发给其他客户端
        while (cc = read(fd, buf, sizeof buf))
        {
            if (cc < 0)
                errexit("recv:%s\n", strerror(errno));
            printf("%s",buf);
            broadcastMsg(fd,buf,cc);
        }
    }
    shutdown(fd,2);
}

//广播消息
void broadcastMsg(int fd, char *buf,int cc)
{
    for (int i = 0; i < QLEN; i++)
    {
        //printf("准备转发...\n");

        if (ssocks[i]!=fd && ssocks[i]!=0) {
            if(write(ssocks[i], buf, cc) < 0){}
        }

    }
    buf = "广播完成\n";
    fputs(buf,stdout);
}

客户端

void *recvMsg(int fd);
int errexit(const char *format, ...);
int connectTCP(const char *host, int port);

#define LINELEN 256

int main(int argc, char *argv[])
{
    char *host = "localhost";
    int port = 3344;
    pthread_t th;
    int sock ;

    switch (argc)
    {
    case 1:
        host = "localhost";
        break;
    case 3:
        port = atoi(argv[2]);
    case 2:
        host = argv[1];
        break;

    default:
        fprintf(stderr, "usage: TCPecho[host[port]]\n");
        exit(1);
    }
    sock = connectTCP(host, port);
    printf("已连接到服务器,fd:%d\n",sock);
    //启动接收线程
    if (pthread_create(&th, NULL,(void *(*)(void *)) recvMsg, (void *)sock) < 0)
        errexit("phread_create:%s\n", strerror(errno));

    //循环处理输入字符
    int outchars;
    char buf[LINELEN + 1];

     while (1)
    {
        if(sock==NULL)
            errexit("与服务器断开连接:%s\n",strerror(errno)) ;
        while (fgets(buf, sizeof(buf), stdin))
        {
            buf[LINELEN] = '\0';
            int cc=sizeof buf;
            //printf("要发送的数据大小:%d\n",cc);
            if(write(sock, buf, sizeof buf)<0){
                printf("发送信息出错\n");
                errexit("send:%s\n", strerror(errno));
            }
            printf("--------\n发送完成\n\n");
            fflush(stdout);
        }
    }
    printf("回到主函数\n");
    exit(0);
}

void *recvMsg(int fd)
{
    int cc=0;
    char buf[LINELEN + 1];
    printf("进入接收线程,fd:%d\n",fd);
    while (1)
    {
        memset(buf,'\0',sizeof(buf));
        while (cc = read(fd, buf, sizeof buf))
        {
            if (cc < 0){
                errexit("recv:%s\n", strerror(errno));
                printf("接收信息出错\n");
                break;
            }
            printf("%s",buf);
            fflush(stdout);
        }
    }
    printf("退出接收线程");
}

完整源代码:
服务器
客户端

你可能感兴趣的:(c语言)