Я хотел бы создать простой TCP-чат с возможностью отправки файлов.
Отправка сообщений другим клиентам работает, но отправка файлов не работает. Мой чат отправляет только несколько байтов файла.
Чат работает следующим образом: сервер запускается и ожидает клиентов, клиенты подключаются к серверу и могут отправлять сообщения другим клиентам через сервер. Я хотел бы разрешить то же самое с файлами.
Сервер написан на C, а Клиент написан на Java (у меня были такие рекомендации).
Сервер:
for (i = 0; i < max_clients; i++) {
sd = client_socket[i];
memset(buffer, 0, 10000);
if (FD_ISSET( sd , &readfds)) {
if ((valread = read( sd , buffer, 1024)) == 0) {
getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);
printf("Host disconnected , ip %s , port %d \n" ,
inet_ntoa(address.sin_addr) , ntohs(address.sin_port));
close( sd );
client_socket[i] = 0;
}
else {
// When message "start" arrived download the file and send it back to other clients
if (strcmp(buffer, "start") == 0) {
uint8_t buff[10000];
// Read chunks of file
while (read( sd , buff, sizeof(buff)) > 0) {
// Sending chunks of file to other clients
for(j=0; j<max_clients; j++) {
int outSock = client_socket[j];
if(outSock != master_socket && outSock != sd) {
send(outSock , buff , sizeof(buff) , 0 );
}
}
}
} else {
buffer[valread] = '\0';
for(j=0; j<max_clients; j++) {
int outSock = client_socket[j];
if(outSock != master_socket && outSock != sd) {
send(outSock , buffer , strlen(buffer) , 0 );
}
}
}
}
}
}
Клиент:
@FXML
void sendFile(ActionEvent event) {
FileChooser fileChooser = new FileChooser();
File file = fileChooser.showOpenDialog(null);
// Send "start" message to let server know that I'm going to send a file
out.println("start");
out.flush();
try {
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
//Get socket's output stream
OutputStream os = clientSocket.getOutputStream();
//Read File Contents into contents array
byte[] contents;
long fileLength = file.length();
long current = 0;
while(current!=fileLength){
int size = 10000;
if(fileLength - current >= size)
current += size;
else{
size = (int)(fileLength - current);
current = fileLength;
}
contents = new byte[size];
bis.read(contents, 0, size);
os.write(contents);
System.out.print("Sending file ... "+(current*100)/fileLength+"% complete!");
}
os.flush();
System.out.println("File sent successfully!");
} catch(Exception e) {
}
}
public ChatWindowController() {
try {
clientSocket = new Socket("127.0.0.1", 54000);
outToServer = new DataOutputStream(clientSocket.getOutputStream());
inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
thread = new Thread() {
@Override
public void run() {
try {
while(isRunning) {
if (ta_display != null) {
String message = inFromServer.readLine();
if (!isDownloadingFile) {
System.out.println(message);
ta_display.appendText(message + '\n');
if (message.equals("start")) {
isDownloadingFile = true;
}
} else {
byte[] contents = new byte[10000];
//Initialize the FileOutputStream to the output file's full path.
FileOutputStream fos = new FileOutputStream("/example/test.png");
BufferedOutputStream bos = new BufferedOutputStream(fos);
InputStream is = clientSocket.getInputStream();
//No of bytes read in one read() call
int bytesRead = 0;
while((bytesRead=is.read(contents))!=-1)
bos.write(contents, 0, bytesRead);
bos.flush();
System.out.println("File saved successfully!");
}
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
};
thread.start();
} catch(Exception e) {
e.printStackTrace();
}
}
Когда я нажимаю кнопку, вызывается метод sendFile, затем я выбираю файл и хочу отправить этот файл, а другие клиенты скачивают его.