用c语言写一个聊天软件
时间: 2024-06-08 19:11:21 浏览: 134
基于C语言的聊天工具
5星 · 资源好评率100%
写一个完整的聊天软件需要考虑很多方面,包括网络通信、用户界面、聊天记录存储等。下面是一个简单的示例,用C语言实现一个基于TCP协议的简单聊天程序。
1. 服务器端代码
```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 BUF_SIZE 100
#define MAX_CLIENTS 10
typedef struct {
int socket;
struct sockaddr_in address;
char name[BUF_SIZE];
} client_info;
client_info clients[MAX_CLIENTS];
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *handle_client(void *arg)
{
int client_socket = *(int *)arg;
char buf[BUF_SIZE];
char message[BUF_SIZE + BUF_SIZE + 2];
int i;
// 接收客户端的名字
if (recv(client_socket, buf, BUF_SIZE, 0) <= 0) {
close(client_socket);
return NULL;
}
strncpy(clients[client_socket].name, buf, BUF_SIZE - 1);
// 广播欢迎消息
sprintf(message, "%s joined the chat.\n", clients[client_socket].name);
pthread_mutex_lock(&mutex);
for (i = 0; i < MAX_CLIENTS; i++) {
if (clients[i].socket > 0 && clients[i].socket != client_socket) {
send(clients[i].socket, message, strlen(message), 0);
}
}
pthread_mutex_unlock(&mutex);
while (1) {
int bytes_received = recv(client_socket, buf, BUF_SIZE, 0);
if (bytes_received <= 0) {
// 客户端断开连接
sprintf(message, "%s left the chat.\n", clients[client_socket].name);
pthread_mutex_lock(&mutex);
for (i = 0; i < MAX_CLIENTS; i++) {
if (clients[i].socket > 0 && clients[i].socket != client_socket) {
send(clients[i].socket, message, strlen(message), 0);
}
}
pthread_mutex_unlock(&mutex);
break;
}
// 发送消息给所有客户端
sprintf(message, "%s: %s", clients[client_socket].name, buf);
pthread_mutex_lock(&mutex);
for (i = 0; i < MAX_CLIENTS; i++) {
if (clients[i].socket > 0 && clients[i].socket != client_socket) {
send(clients[i].socket, message, strlen(message), 0);
}
}
pthread_mutex_unlock(&mutex);
}
// 移除客户端信息
pthread_mutex_lock(&mutex);
for (i = 0; i < MAX_CLIENTS; i++) {
if (clients[i].socket == client_socket) {
clients[i].socket = -1;
break;
}
}
pthread_mutex_unlock(&mutex);
close(client_socket);
return NULL;
}
int main(int argc, char *argv[])
{
int server_socket, client_socket;
struct sockaddr_in server_address, client_address;
socklen_t client_address_len;
pthread_t thread_id;
int i;
// 创建服务器端套接字
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 绑定地址和端口
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = INADDR_ANY;
server_address.sin_port = htons(8888);
if (bind(server_socket, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听连接请求
if (listen(server_socket, MAX_CLIENTS) == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
// 初始化客户端列表
for (i = 0; i < MAX_CLIENTS; i++) {
clients[i].socket = -1;
}
// 等待客户端连接
while (1) {
client_address_len = sizeof(client_address);
client_socket = accept(server_socket, (struct sockaddr *)&client_address, &client_address_len);
if (client_socket == -1) {
perror("accept");
continue;
}
// 添加客户端信息
for (i = 0; i < MAX_CLIENTS; i++) {
if (clients[i].socket == -1) {
clients[i].socket = client_socket;
clients[i].address = client_address;
strcpy(clients[i].name, "");
break;
}
}
if (i == MAX_CLIENTS) {
printf("Too many clients\n");
close(client_socket);
continue;
}
// 创建线程处理客户端连接
pthread_create(&thread_id, NULL, handle_client, (void *)&client_socket);
}
close(server_socket);
return 0;
}
```
2. 客户端代码
```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 BUF_SIZE 100
void *receive_message(void *arg)
{
int socket = *(int *)arg;
char buf[BUF_SIZE];
while (1) {
int bytes_received = recv(socket, buf, BUF_SIZE, 0);
if (bytes_received <= 0) {
printf("Server disconnected\n");
break;
}
printf("%s", buf);
}
close(socket);
exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[])
{
int socket_fd;
struct sockaddr_in server_address;
pthread_t thread_id;
char name[BUF_SIZE];
char message[BUF_SIZE];
// 创建客户端套接字
socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (socket_fd == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 连接服务器
memset(&server_address, 0, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
server_address.sin_port = htons(8888);
if (connect(socket_fd, (struct sockaddr *)&server_address, sizeof(server_address)) == -1) {
perror("connect");
exit(EXIT_FAILURE);
}
// 输入名字
printf("Enter your name: ");
fgets(name, BUF_SIZE, stdin);
name[strlen(name) - 1] = '\0';
send(socket_fd, name, strlen(name), 0);
// 创建接收消息的线程
pthread_create(&thread_id, NULL, receive_message, (void *)&socket_fd);
// 发送消息
while (1) {
fgets(message, BUF_SIZE, stdin);
if (send(socket_fd, message, strlen(message), 0) == -1) {
perror("send");
break;
}
}
close(socket_fd);
return 0;
}
```
以上代码仅提供参考,具体实现还需要根据实际需求进行修改和完善。
阅读全文