1、服务器端代码
创建套接字:使用socket()
函数创建一个流式套接字,用于基于 TCP 的通信。
绑定端口:通过bind()
函数将套接字与本地地址和端口绑定,以便接收客户端的连接请求。
监听连接:利用listen()
函数使套接字进入监听状态,准备接受客户端的连接。
接受连接:当有客户端连接时,accept()
函数会返回一个新的套接字描述符,用于与该客户端进行通信。
收发消息:使用recv()
和send()
函数在连接的两端进行消息的接收和发送。
关闭连接:通信结束后,使用close()
函数关闭套接字,释放资源。
2、客户端代码
创建套接字:同样使用socket()
函数创建一个流式套接字。
连接服务器:使用connect()
函数与服务器建立连接,需要提供服务器的 IP 地址和端口号。
收发消息:通过send()
函数向服务器发送消息,使用recv()
函数接收服务器的回复。
关闭连接:通信完成后,调用close()
函数关闭套接字。
3、示例代码
服务器端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 #define MAX_BUFFER_SIZE 1024 int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[MAX_BUFFER_SIZE] = {0}; const char *message = "Hello from server"; // 创建 socket 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); // 绑定 socket 到地址和端口 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听连接 if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // 接受客户端连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("accept"); exit(EXIT_FAILURE); } read(new_socket, buffer, 1024); printf("Message from client: %s ", buffer); send(new_socket, message, strlen(message), 0); printf("Hello message sent "); close(new_socket); close(server_fd); return 0; }
客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8080 #define SERVER_IP "127.0.0.1" int main() { int sock = 0; struct sockaddr_in serv_addr; char *message = "Hello from client"; char buffer[1024] = {0}; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf(" Socket creation error "); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 转换地址 if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) { printf(" Invalid address "); return -1; } // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf(" Connection failed "); return -1; } send(sock, message, strlen(message), 0); printf("Hello message sent "); read(sock, buffer, 1024); printf("%s ", buffer); close(sock); return 0; }
1、实现思路:文件传输程序需要在客户端和服务器之间建立一个可靠的连接,用于传输文件数据,可以选择使用 TCP 协议来保证数据的可靠传输,服务器端负责监听客户端的连接请求,接收客户端发送的文件请求,并将指定文件发送给客户端,客户端则向服务器发送文件请求,接收服务器传输的文件数据,并将其保存到本地文件中。
2、关键技术:文件传输过程中需要考虑文件的读取和写入操作,以及网络通信中的数据传输效率和可靠性,可以使用缓冲区来暂存文件数据,提高传输效率,需要进行错误处理,确保在网络异常或文件操作失败时能够及时通知对方并采取相应的措施。
3、示例代码(简化版)
服务器端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PORT 8888 #define BUFFER_SIZE 1024 void send_file(FILE *fp, int sockfd) { char data[BUFFER_SIZE] = {0}; while (fgets(data, BUFFER_SIZE, fp) != NULL) { if (send(sockfd, data, sizeof(data), 0) == -1) { perror("Error in sending file."); exit(1); } memset(data, 0, BUFFER_SIZE); } } int main() { int server_fd, new_socket; struct sockaddr_in address; int addrlen = sizeof(address); char buffer[BUFFER_SIZE] = {0}; // 创建 socket 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); // 绑定 socket 到地址和端口 if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { perror("bind failed"); exit(EXIT_FAILURE); } // 监听连接 if (listen(server_fd, 3) < 0) { perror("listen"); exit(EXIT_FAILURE); } // 接受客户端连接 if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) { perror("accept"); exit(EXIT_FAILURE); } FILE *fp = fopen("fileToSend.txt", "r"); if (fp == NULL) { perror("File not found"); exit(EXIT_FAILURE); } send_file(fp, new_socket); printf("File data sent successfully. "); close(new_socket); close(server_fd); return 0; }
客户端:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define PORT 8888 #define SERVER_IP "127.0.0.1" int main() { int sock = 0; struct sockaddr_in serv_addr; char buffer[1024] = {0}; char *filename = "receivedFile.txt"; FILE *fp; // 创建 socket if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf(" Socket creation error "); return -1; } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(PORT); // 转换地址 if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0) { printf(" Invalid address/ Address not supported "); return -1; } // 连接服务器 if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { printf(" Connection Failed "); return -1; } fp = fopen(filename, "w"); if (fp == NULL) { perror("File not opened for writing"); exit(EXIT_FAILURE); } while (1) { int bytesReceived = recv(sock, buffer, 1024, 0); if (bytesReceived <= 0) { break; } fwrite(buffer, 1, bytesReceived, fp); } printf("File received and saved as %s ", filename); close(sock); fclose(fp); return 0; }