一:要求服務器
利用Linux Socket進行文件傳輸,本次只支持client端向sever端上傳文件less
二:實現提示:socket
client.cspa
client的參數有兩個,分別是服務器主機名和端口;code
在while循環中輸入你想要傳輸的文件名,而後創建socket,經過服務器主機名和端口鏈接服務器;blog
打開文件,在while循環中讀取文件,發送文件ip
sever.cget
在while循環中accept客戶端的鏈接,接受數據並寫入文件中input
(也能夠選擇select()accept客戶端的鏈接,在while循環中接受數據並寫入文件中)string
三:程序
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; }
四:現象
略(已實驗,運行正確)