实现一个基于多线程或多进程的TCP聊天服务端程序,可以在一个终端窗口中显示多个客户端的聊天消息,并且和多个客户端同时聊天。

//Client_multiple.c

#include "net.h"

char recv_buf[1500],send_buf[1024];
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';
            printf("%s\n",recv_buf);
        }
    }
}

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]);
    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);
    }
    char name[20];
    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;    
}

 

//Server_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 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(SERVPORT);
    my_addr.sin_addr.s_addr=INADDR_ANY;
    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 型)
        }
}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 对于用C语言实现TCP客户端服务端,要求是服务器可以同时连接多个客户端,并能够打印多个客户端发来的消息,可以使用socket编程的方式来实现。首先,在服务器端,使用socket()函数创建一个TCP socket,并使用bind()函数将其绑定到指定的端口号。然后,使用listen()函数将socket处于监听状态,以等待客户端的连接。一旦客户端连接到服务器服务器就可以使用accept()函数接受客户端的连接,然后使用read()函数从客户端接收消息,并使用write()函数将消息发送客户端。最后,服务器可以使用close()函数关闭与客户端的连接。 ### 回答2: 实现用C语言编写TCP协议的客户端服务器端的实例,并能同时处理多个客户端连接并打印客户端发来的消息,需要以下步骤: 1. 导入相关头文件和库函数:在C语言,可以使用sys/socket.h头文件和socket函数库来实现TCP协议的客户端服务器端编程。 2. 创建一个服务器端的套接字:使用socket函数创建一个服务器端的套接字,指定使用TCP协议。 3. 绑定服务器地址和端口号:使用bind函数将服务器地址和端口号与套接字绑定在一起。 4. 监听客户端的连接请求:使用listen函数监听来自客户端的连接请求。 5. 接受客户端连接:使用accept函数接受客户端的连接请求,并创建与客户端通信的套接字。 6. 创建多线程多进程:可以使用多线程多进程实现同时处理多个客户端连接的功能。 7. 打印客户端发来的消息:使用recv函数接收客户端发来的消息,并打印出来。 8. 处理客户端连接断开:当客户端连接断开时,需要使用close函数关闭对应的套接字。 需要注意的是,在多客户端连接情况下,服务器端需要具备处理并发请求的能力,可以使用线程池或进程池等方式来实现。 以上是一个简单的实现方法,你可以根据具体需求进行修改和优化。 ### 回答3: 使用C语言实现TCP实现客户端服务端是一种常见的网络编程任务。下面是一个简单的例子: 首先,服务端的代码如下所示: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define PORT 8888 #define MAX_CLIENTS 5 int main() { int server_fd, new_socket, valread; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[1024]; // 创建套接字 if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("socket failed"); exit(EXIT_FAILURE); } // 设置服务器地址和端口 address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); // 绑定套接字到指定地址和端口 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听连接 if (listen(server_fd, MAX_CLIENTS) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } printf("Server listening on port %d\n", PORT); while (1) { // 接受新连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept failed"); exit(EXIT_FAILURE); } printf("New client connected\n"); // 读取客户端发来的消息 while ((valread = read(new_socket, buffer, 1024)) > 0) { printf("Client message: %s\n", buffer); memset(buffer, 0, sizeof(buffer)); } printf("Client disconnected\n"); // 关闭连接 close(new_socket); } return 0; } 然后,客户端的代码如下: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #define SERVER_IP "127.0.0.1" #define PORT 8888 int main() { int sock = 0; struct sockaddr_in serv_addr; char message[1024]; // 创建套接字 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket failed"); exit(EXIT_FAILURE); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 将IP地址字符串转换为二进制形式 if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) { perror("address conversion failed"); exit(EXIT_FAILURE); } // 连接到服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { perror("connection failed"); exit(EXIT_FAILURE); } // 输入消息 printf("Enter message: "); fgets(message, sizeof(message), stdin); // 发送消息服务器 if (send(sock, message, strlen(message), 0) < 0) { perror("send failed"); exit(EXIT_FAILURE); } printf("Message sent\n"); // 关闭连接 close(sock); return 0; } 这样就实现一个简单的可以同时连接多个客户端并打印客户端消息TCP服务端客户端

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值