一:要求
利用Linux Socket进行文件传输,本次只支持client端向sever端上传文件
二:实现提示:
client.c
client的参数有两个,分别是服务器主机名和端口;
在while循环中输入你想要传输的文件名,然后建立socket,通过服务器主机名和端口连接服务器;
打开文件,在while循环中读取文件,发送文件
sever.c
在while循环中accept客户端的连接,接受数据并写入文件中
(也可以选择select()accept客户端的连接,在while循环中接受数据并写入文件中)
三:程序
sever.c (服务器端)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/types.h> #include <unistd.h> #include <netdb.h> #include <sys/stat.h> #include <fcntl.h> #define PORT 5168 #define MSGLEN 1024 int main(int argc, char **argv) { int severFd, clientFd; int fp,flags; socklen_t addrlen; struct sockaddr_in severAddr, clientAddr; char recvBuff[MSGLEN]; char filename[100]; int recv_len; if((severFd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("sockst() error"); exit(-1); } severAddr.sin_family = AF_INET; severAddr.sin_port = htons(PORT); severAddr.sin_addr.s_addr = htons(INADDR_ANY); bzero(&severAddr.sin_zero, 8); if(bind(severFd, (struct sockaddr*)&severAddr, sizeof(struct sockaddr)) == -1) { perror("bind() error"); exit(-1); } if(listen(severFd, 1) == -1) { perror("listen() error"); exit(-1); } addrlen =sizeof(struct sockaddr); while(1) { flags = 0; if((clientFd = accept(severFd, (struct sockaddr*)&clientAddr, &addrlen)) == -1){ perror("accept() error"); exit(-1); } printf("recv file fome ip:%s port: %d\n", inet_ntoa(clientAddr.sin_addr), ntohs(clientAddr.sin_port)); if(recv(clientFd, filename, strlen(filename), 0) < 0){ perror("recv filename error"); break; //less } fp = open(filename, O_RDWR | O_CREAT, 777); while((recv_len = recv(clientFd, recvBuff, MSGLEN, 0)) > 0) { flags++; if(flags == 1) { printf("recv file start"); } else { printf("."); } if(write(fp, recvBuff, recv_len)) { bzero(&recvBuff, MSGLEN); }else { perror("write() error"); break; } } if(flags == 0) perror("recv() error"); if(flags > 0){ printf("\nrecv success\n"); close(clientFd); } } close(severFd); return 0; }
client.c(客户端)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/types.h> #include <unistd.h> #include <netdb.h> #include <sys/stat.h> #include <fcntl.h> #define MSGLEN 1024 struct ADDR { int port; char name[32]; }; void file_send(struct ADDR addr, char *filename) { int sockfd; FILE* fp; struct sockaddr_in sevrAddr; struct hostent *host; char readBuff[MSGLEN]; int len; host = gethostbyname(addr.name); if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ perror("socket() error"); exit(-1); }else printf("socket ok\n"); sevrAddr.sin_family = AF_INET; sevrAddr.sin_port = htons(addr.port); sevrAddr.sin_addr = *((struct in_addr*)host->h_addr); bzero(&sevrAddr.sin_zero, 8); // printf("ok2\n"); if(connect(sockfd, (struct sockaddr*)&sevrAddr, sizeof(struct sockaddr)) == -1){ perror("connect() error"); exit(-1); }else printf("connect ok\n"); // fp = open(filename, O_RDONLY); if(send(sockfd, filename, sizeof(filename), 0) < 0) { perror("send filename error"); exit(-1); } fp = fopen(filename, "rb"); if(fp != NULL){ printf("send file"); while(1) { if((len = fread(readBuff, 1, MSGLEN, fp)) > 0) { if(send(sockfd, readBuff, len, 0) < 0){ perror("send() error"); exit(-1); } else { printf("."); bzero(&readBuff, MSGLEN); } } else if(len == 0){ //等于0表示文件已到末尾 // send(sockfd, readBuff, strlen(readBuff), 0); printf("\nfile send success\n"); break; } else { perror("read() error"); exit(-1); } } }else { printf("open file failed\n"); exit(-1); } fclose(fp); close(sockfd); } int main(int argc, char **argv) { struct ADDR useraddr; char filename[100]; if(argc != 3) { printf("Usage: ./client [hostname] [port]"); exit(-1); } strcpy(useraddr.name, argv[1]); useraddr.port = atoi(argv[2]); while(1) { printf("please input filename of you want send\n"); fgets(filename, 20, stdin); filename[strlen(filename)-1] = 0; // printf("ok1\n"); file_send(useraddr, filename); } return 0; }
四:现象
略(已实验,运行正确)