Я пытаюсь выполнить несколько функций, используя следующие два сценария. Я пытаюсь загрузить файлы с клиента на сервер, загрузить файлы с сервера на клиент, изменить каталог сервера и затем загрузить список файлов в этом каталоге с сервера на клиент.
Когда я запускаюмои текущие сценарии, я могу ввести имя файла для загрузки, но он не загружается и сразу переходит к следующей функции (для загрузки файла). Если я укажу файл для загрузки, он застрянет.
Я предполагаю, что моя проблема заключается в том, что сокеты принимают и закрывают сокет после выполнения действия, но я не уверен, как это сделать. ,Я включил код моего сервера и клиента ниже. Имейте в виду, что создание сокетов, привязка и прослушивание работают правильно.
client.c
/* A simple echo client using TCP */
#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <strings.h>
#define SERVER_TCP_PORT 3000 /* well-known port */
#define BUFLEN 256 /* buffer length */
#define sendrecvflag 0
#define cipherKey 'S'
// function to clear buffer
void clearBuf(char* b)
{
int i;
for (i = 0; i < BUFLEN; i++)
b[i] = '\0';
}
// function for decryption
char Cipher(char ch)
{
return ch ^ cipherKey;
}
// function to receive file
int recvFile(char* buf, int s)
{
int i;
char ch;
for (i = 0; i < s; i++) {
ch = buf[i];
ch = Cipher(ch);
if (ch == EOF)
return 1;
else
printf("%c", ch);
}
return 0;
}
int main(int argc, char **argv)
{
int n, i, bytes_to_read, b, nBytes;
int sockfd, port;
struct hostent *hp;
struct sockaddr_in server;
char *host, *bp, net_buf[BUFLEN], input[20];
int addrlen = sizeof(server);
switch(argc){
case 2:
host = argv[1];
port = SERVER_TCP_PORT;
break;
case 3:
host = argv[1];
port = atoi(argv[2]);
break;
default:
fprintf(stderr, "Usage: %s host [port]\n", argv[0]);
exit(1);
}
/* Create a stream socket */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "Can't creat a socket\n");
exit(1);
}
/* Bind an address to the socket */
bzero((char *)&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
if (hp = gethostbyname(host))
bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
else if ( inet_aton(host, (struct in_addr *) &server.sin_addr) ){
fprintf(stderr, "Can't get server's address\n");
exit(1);
}
/* Connecting to the server */
if (connect(sockfd, (struct sockaddr *)&server, addrlen) == -1){
fprintf(stderr, "Can't connect \n");
exit(1);
}
while(1){
//This is for file upload--------------
printf("Specify file to upload:");
scanf("%s", &input);
//need to create this file in the file system.
FILE *fp = fopen(input, "rb");
if(fp == NULL){
perror("File doesnt exist");
return 2;
}
while( (b = fread(net_buf, 1, sizeof(net_buf), fp))>0 ){
send(sockfd, net_buf, b, sendrecvflag);
}
printf("done sending content");
fclose(fp);
//This is for file download---------------
printf("Specify the file that you want to download from server:");
scanf("%s", net_buf);
sendto(sockfd, net_buf, BUFLEN,
sendrecvflag, (struct sockaddr*)&server,
addrlen);
printf("\n---------Data Received---------\n");
while(1){
// receive
clearBuf(net_buf);
nBytes = recvfrom(sockfd, net_buf, BUFLEN,
sendrecvflag, (struct sockaddr*)&server,
&addrlen);
// process
if (recvFile(net_buf, BUFLEN)) {
break;
}
}
//This is for Change in directory
printf("Specify the directory you want to change to: ");
scanf("%s", net_buf);
sendto(sockfd, net_buf, BUFLEN,
sendrecvflag, (struct sockaddr*)&server,
addrlen);
printf("\n---------Directory Has been Changed---------\n");
//This is for Listing directory
printf("Specify the directory(ex.'.'): ");
scanf("%s", net_buf);
sendto(sockfd, net_buf, BUFLEN,
sendrecvflag, (struct sockaddr*)&server,
addrlen);
printf("\n---------Directory Data Received---------\n");
while(1){
// receive
clearBuf(net_buf);
nBytes = recvfrom(sockfd, net_buf, BUFLEN,
sendrecvflag, (struct sockaddr*)&server,
&addrlen);
// process
if (recvFile(net_buf, BUFLEN)) {
break;
}
}
//End
}
close(sockfd);
return(0);
}
server.c
/* A simple echo server using TCP */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <string.h>
#define SERVER_TCP_PORT 3000 /* well-known port */
#define BUFLEN 256 /* buffer length */
#define cipherKey 'S'
#define nofile "File Not Found!"
#define sendrecvflag 0
int echod(int);
void reaper(int);
// function to clear buffer
void clearBuf(char* b)
{
int i;
for (i = 0; i < BUFLEN; i++)
b[i] = '\0';
}
// function for decryption
char Cipher(char ch)
{
return ch ^ cipherKey;
}
// function sending file
int sendFile(FILE* fp, char* buf, int s)
{
int i, len;
if (fp == NULL) {
strcpy(buf, nofile);
len = strlen(nofile);
buf[len] = EOF;
for (i = 0; i <= len; i++)
buf[i] = Cipher(buf[i]);
return 1;
}
char ch, ch2;
for (i = 0; i < s; i++) {
ch = fgetc(fp);
ch2 = Cipher(ch);
buf[i] = ch2;
if (ch == EOF)
return 1;
}
return 0;
}
int main(int argc, char **argv)
{
int sockfd, new_sd, client_len, port, confd = 0,b,tot, nBytes;
struct sockaddr_in server, client;
char net_buf[BUFLEN];
int addrlen = sizeof(server);
switch(argc){
case 1:
port = SERVER_TCP_PORT;
break;
case 2:
port = atoi(argv[1]);
break;
default:
fprintf(stderr, "Usage: %d [port]\n", argv[0]);
exit(1);
}
/* Create a stream socket */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
fprintf(stderr, "Can't creat a socket\n");
exit(1);
}
/* Bind an address to the socket */
bzero((char *)&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr *)&server, addrlen) == -1){
fprintf(stderr, "Can't bind name to socket\n");
exit(1);
}
if(listen(sockfd, 10) < 0) {
perror("listen");
exit(1);
}
while(1) {
//This is for file upload
printf("This is sending file");
confd = accept(sockfd, (struct sockaddr*)NULL, NULL);
if (confd==-1) {
perror("Accept");
continue;
}
//Should create a text file.
FILE* fp = fopen( "test.txt", "wb");
tot=0;
if(fp != NULL){
while( (b = recv(confd, net_buf, BUFLEN,sendrecvflag))> 0 ) {
tot+=b;
fwrite(net_buf, 1, b, fp);
}
printf("Received byte: %d\n",tot);
if (b<0)
perror("Error recieving the file");
fclose(fp);
} else {
perror("File doesnt exist");
}
close(confd);
//This is for file download
printf("\nWaiting for file name...\n");
confd = accept(sockfd, (struct sockaddr*)NULL, NULL);
if (confd==-1){
perror("Accept");
continue;
}
// receive file name
clearBuf(net_buf);
nBytes = recvfrom(sockfd, net_buf,
BUFLEN, sendrecvflag,
(struct sockaddr *)&server, &addrlen);
fp = fopen(net_buf, "r");
printf("\nFile Name Received: %s\n", net_buf);
if (fp == NULL)
printf("\nFile open failed!\n");
else
printf("\nFile Successfully opened!\n");
while (1) {
// process
if (sendFile(fp, net_buf, BUFLEN)) {
sendto(sockfd, net_buf, BUFLEN,
sendrecvflag,
(struct sockaddr*)&server, addrlen);
break;
}
// send
sendto(sockfd, net_buf, BUFLEN,
sendrecvflag,
(struct sockaddr*)&server, addrlen);
clearBuf(net_buf);
}
if (fp != NULL)
fclose(fp);
//This is for Change in directory
clearBuf(net_buf);
nBytes = recvfrom(sockfd, net_buf,
BUFLEN, sendrecvflag,
(struct sockaddr*)&server, &addrlen);
chdir(net_buf);
//This is for Listing directory
clearBuf(net_buf);
nBytes = recvfrom(sockfd, net_buf,
BUFLEN, sendrecvflag,
(struct sockaddr*)&server, &addrlen);
DIR *d;
struct dirent *dir;
d = opendir(net_buf);
if (d){
while ((dir = readdir(d)) != NULL)
{
// send
strcpy(net_buf,dir->d_name );
sendto(sockfd, net_buf, BUFLEN,
sendrecvflag,
(struct sockaddr*)&server, addrlen);
clearBuf(net_buf);
}
closedir(d);
}else{
printf("File Directory doesnt exist");
}
//End
}
}
У меня есть функции, которыезашифровать и отправить данные в обоих. Это не обязательно, но я хотел понять шифрование на очень высоком уровне. Основной код начинается после первого цикла while. Там не так много кода. И последнее, что следует упомянуть, - это то, что IP и номер порта отправляются в качестве аргумента, опять же, это не то, что требует внимания, так как соединение установлено успешно.