我想创建一个带有发送文件选项的简单 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 方法被调用时,然后我选择文件,我想发送这个文件,并与其他客户端下载它。
最佳答案
我写了一个类似的聊天例子https://github.com/foreverpersist/socket/blob/master/chatroom.c .
文件传输是通过P2P实现的
- 服务器告诉
<IP:PORT>
发送方和接收方的 s。 - 发送方和接收方直接相互连接。
- 发送方将文件发送给接收方。
- 发送方和接收方关闭连接。
正如您的项目中发生的情况,当传输路径为 Sender -> Server -> Receiver
的文件时,大文件的内容如果不小心处理可能会不完整。所以,我只传输路径为 Sender -> Receiver
的文件.
关于java - 聊天选项发送文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54079401/