我想要一段完整的代码,在Ubuntu环境下实现客户端和服务器端的相互通信,程序要具备即时聊天和文件传送功能,使用socket编程
时间: 2024-02-11 15:08:51 浏览: 104
以下是一个基于socket编程的简单即时聊天和文件传送的C语言代码示例,可以在Ubuntu环境下编译运行:
服务器端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 8888
#define MAX_CLIENTS 10
#define BUFSIZE 1024
int clients[MAX_CLIENTS];
int num_clients = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *client_handler(void *arg);
int main(int argc, char *argv[]) {
int server_fd, client_fd;
struct sockaddr_in server_addr, client_addr;
pthread_t tid;
int opt = 1;
// 创建服务器socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 设置socket选项
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt)) == -1) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
// 绑定socket到本地地址和端口
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind");
exit(EXIT_FAILURE);
}
// 监听连接请求
if (listen(server_fd, MAX_CLIENTS) == -1) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Server started, listening on port %d\n", PORT);
while (1) {
int addrlen = sizeof(client_addr);
// 接受客户端连接请求
if ((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, (socklen_t *)&addrlen)) == -1) {
perror("accept");
continue;
}
// 创建新线程处理客户端连接
if (pthread_create(&tid, NULL, client_handler, (void *)&client_fd) != 0) {
perror("pthread_create");
continue;
}
printf("New client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
close(server_fd);
return 0;
}
void *client_handler(void *arg) {
int client_fd = *(int *)arg;
char buf[BUFSIZE];
int nbytes;
// 加锁
pthread_mutex_lock(&mutex);
// 添加到客户端列表
clients[num_clients++] = client_fd;
// 解锁
pthread_mutex_unlock(&mutex);
while (1) {
// 接收客户端发送的消息
if ((nbytes = recv(client_fd, buf, BUFSIZE, 0)) <= 0) {
// 客户端关闭连接或出错
break;
}
buf[nbytes] = '\0';
// 广播消息给其他客户端
pthread_mutex_lock(&mutex);
for (int i = 0; i < num_clients; i++) {
if (clients[i] != client_fd) {
send(clients[i], buf, strlen(buf), 0);
}
}
pthread_mutex_unlock(&mutex);
}
// 关闭连接
close(client_fd);
// 从客户端列表中删除
pthread_mutex_lock(&mutex);
for (int i = 0; i < num_clients; i++) {
if (clients[i] == client_fd) {
for (int j = i; j < num_clients - 1; j++) {
clients[j] = clients[j + 1];
}
num_clients--;
break;
}
}
pthread_mutex_unlock(&mutex);
printf("Client disconnected\n");
return NULL;
}
```
客户端代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define SERVER_IP "127.0.0.1"
#define PORT 8888
#define BUFSIZE 1024
void *recv_thread(void *arg);
int main(int argc, char *argv[]) {
int sock_fd;
struct sockaddr_in server_addr;
char buf[BUFSIZE];
pthread_t tid;
// 创建客户端socket
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror("socket");
exit(EXIT_FAILURE);
}
// 连接服务器
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(PORT);
if (connect(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("connect");
exit(EXIT_FAILURE);
}
printf("Connected to server\n");
// 创建接收线程
if (pthread_create(&tid, NULL, recv_thread, (void *)&sock_fd) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 发送消息
while (1) {
printf("Enter message: ");
fgets(buf, BUFSIZE, stdin);
buf[strlen(buf) - 1] = '\0';
if (send(sock_fd, buf, strlen(buf), 0) == -1) {
perror("send");
break;
}
}
close(sock_fd);
return 0;
}
void *recv_thread(void *arg) {
int sock_fd = *(int *)arg;
char buf[BUFSIZE];
int nbytes;
while (1) {
// 接收服务器发送的消息
if ((nbytes = recv(sock_fd, buf, BUFSIZE, 0)) <= 0) {
// 服务器关闭连接或出错
break;
}
buf[nbytes] = '\0';
printf("Received message: %s\n", buf);
}
printf("Disconnected from server\n");
return NULL;
}
```
上述代码实现了一个简单的聊天室,运行服务器端后,可以启动多个客户端连接到服务器端,客户端之间可以相互发送消息。如果要实现文件传送功能,可以在客户端发送文件前先发送一个文件头,包含文件名和文件大小等信息,在服务器端接收文件时解析文件头,根据文件大小逐步接收文件内容即可。
阅读全文