当前位置:首页 > 行业动态 > 正文

c 网络编程 聊天

用C语言进行网络编程实现聊天功能,需借助socket编程,创建客户端和服务器端,通过套接字连接传输消息。

一、基本概念

1、套接字:是网络通信的基本组件,允许不同计算机间的进程相互通信,在C语言中,利用socket API可以创建套接字,实现进程间的通信。

2、客户端-服务器模型:网络通信主要基于客户端-服务器模型,其中一个进程(服务器)提供服务,而另一个进程(客户端)请求服务。

3、TCP协议:简单聊天室通常运行在TCP协议之上,以保证数据传输的可靠性。

二、服务器端设计

1、创建套接字:使用socket()函数创建新的通信端点。

2、绑定地址:将套接字与特定的IP地址和端口号绑定,使用bind()函数。

c 网络编程 聊天  第1张

3、监听连接:服务器端使用listen()函数监听来自客户端的连接请求。

4、接受连接accept()函数用于接受客户端的连接请求,并返回一个新的套接字用于与客户端通信。

5、接收和发送数据:使用recv()read()函数接收客户端发送的数据,使用send()write()函数向客户端发送数据。

6、多线程处理:为了同时处理多个客户端,服务器端可能需要使用多线程或多进程,每有一个客户端连接到服务器,服务器便会创建一个线程用来与该客户端通信,主线程继续等待其他客户端的连接。

c 网络编程 聊天  第2张

7、存储客户端信息:由于服务器端需要将接收到的消息发送给正在连接的所有客户端,所以需要存储客户端的信息,这可以通过数组或链表来实现。

三、客户端设计

1、创建套接字:与服务器端类似,客户端也使用socket()函数创建套接字。

2、连接到服务器:客户端使用connect()函数尝试连接到服务器。

3、发送和接收数据:客户端通过send()write()函数向服务器发送数据,通过recv()read()函数接收服务器发送的数据。

4、用户界面:客户端需要提供用户界面,允许用户输入消息,并通过套接字将消息发送到服务器,同时接收来自其他客户端的消息。

c 网络编程 聊天  第3张

5、多线程处理:由于客户端获取用户输入(如fgets)和接收服务器端消息(如recv)时都会阻塞,所以客户端也需要采用多线程,主线程负责发送消息,子线程负责接收消息。

四、示例代码

以下是一个简单的C语言实现的聊天室示例代码框架,仅供参考:

服务器端代码示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void *handle_client(void *socket_desc) {
    int sock = *(int*)socket_desc;
    char client_message[BUFFER_SIZE];
    int read_size;
    while ((read_size = recv(sock, client_message, BUFFER_SIZE, 0)) > 0) {
        write(sock, client_message, strlen(client_message));
    }
    if (read_size == 0) {
        puts("Client disconnected");
        fflush(stdout);
    } else if (read_size == -1) {
        perror("recv failed");
    }
    free(socket_desc);
    return 0;
}
int main() {
    int socket_desc, client_sock, c, *new_sock;
    struct sockaddr_in server, client;
    socket_desc = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        printf("Could not create socket");
    }
    puts("Socket created");
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons(PORT);
    if (bind(socket_desc, (struct sockaddr *)&server, sizeof(server)) < 0) {
        perror("bind failed. Error");
        return 1;
    }
    puts("bind done");
    listen(socket_desc, 3);
    puts("Waiting for incoming connections...");
    c = sizeof(struct sockaddr_in);
    while ((client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c))) {
        puts("Connection accepted");
        pthread_t sniffer_thread;
        new_sock = malloc(1);
        *new_sock = client_sock;
        if (pthread_create(&sniffer_thread, NULL, handle_client, (void*) new_sock) < 0) {
            perror("could not create thread");
            return 1;
        }
        puts("Handler assigned");
    }
    if (client_sock < 0) {
        perror("accept failed");
        return 1;
    }
    return 0;
}

客户端代码示例

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#define PORT 8080
#define BUFFER_SIZE 1024
void *receive_messages(void *socket_desc) {
    int sock = *(int*)socket_desc;
    char server_reply[BUFFER_SIZE];
    int read_size;
    while ((read_size = recv(sock, server_reply, BUFFER_SIZE, 0)) > 0) {
        server_reply[read_size] = '
0