I would like to create a simple TCP chat with option to send files.
Sending messages to other clients works, but sending files doesn't work. My chat sends only few bytes of file.
Chat works like: Server starts up and wait for clients, Clients connect to server and they can send messages to other clients through the server. I would like to allow to the same with files.
Server is wrote in C, and Client is wrote in Java (I had guidelines like that).
Server:
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 );
}
}
}
}
}
}
Client:
#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();
}
}
When I click button sendFile method is called, then I choose file and I want to send this file, and with other clients download it.
I have written a similar example for chatting at https://github.com/foreverpersist/socket/blob/master/chatroom.c.
File transferring is implemented by P2P
Server tells <IP:PORT>s of sender and receiver to each other.
Sender and receiver connect to each other directly.
Sender sends file to receiver.
Sender and receiver close the connection.
As what happens in your project, when transferring files with path Sender -> Server -> Receiver, the content of large files may be incomplete if you don't deal carefully. So, I just transfer files with path Sender -> Receiver.
Ok, there is a bug on the server when receiving the file:
//client sends 10000 bytes of data in chunks of unknown size
//receive one chunk of unknown size
while (read( sd , buff, sizeof(buff)) > 0) {
for(j=0; j<max_clients; j++) {
int outSock = client_socket[j];
if(outSock != master_socket && outSock != sd) {
// Send 10000 bytes aka the received chunk and whatever else is in the buffer to all clients
send(outSock , buff , sizeof(buff) , 0 );
}
}
You need to either receive all the data first and then send it to the clients, or only send the size of the chunk many bytes, like in the File writer in the client or as follows:
int chunk = 0;
while ((chunk = read( sd , buff, sizeof(buff))) > 0) {
...
send(outSock , buff , chunk , 0);
Also Im not certain if the Client file writing code works, you should ensure that no following messages are written to file accidently.
Related
This question already has an answer here:
Java TCP server cannot receive message from more than one client
(1 answer)
Closed 5 years ago.
[Edit: This post has been marked as duplicate without reviewing properly. The two posts address completely different problem which the reviewer did not take time to carefully read.]
The server will connect to three instances of client. The server has three threads to receive requests from these three clients. Each of the three instances of client will have a ServerThread (the server requests for file or file list from this thread) and a UserThread (it will take user input and communicated with the server and receive file/file list depending on the user input).
Let's say client_0 wants a file that is in possession of client_1. When UserThread of client_0 requests the server for the file, the server communicates with ServerThread of client_1 and ServerThread of client_1 sends the byteArray of the file to the server. The server then sends the byteArray back to the UserThread of client_0 and client_0 then saves the byteArray as a file.
I am using the same type of code for the server to receive the bytearray from client_1 and for client_0 to receive the byteArray from the server. The server's code works perfectly everytime and receives the byteArrayperfectly but in client_0, the loop that receives the byteArray gets stuck at the last part of the file although the same type of loop is working perfectly in server. The variable position holds how much of the byteArray has been received and it doesn't reach the FILE_SIZE in the client_0 but does so in server without any problem. The System.out.println() statements confirm this.
In addition, this problem in client_0 is happening 90% of the time. In the other 10%, the loop in client_0 works just like it is supposed to! Why is this happening?
The codes are long but if anyone manages to go through and give some suggestion, it will be a great help.
Server:
package server;
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) throws Exception {
String[] id={"cp 1","cp 2","cp 3"}, pass={"123","456","789"};
ServerSocket welcome = new ServerSocket(6000), tmpSocket;
Socket STsocket, UTsocket;
int startSTport = 6001;
int startUTport = 6011;
// for ServerThread of client
BufferedReader STmsgFrom[] = new BufferedReader[3];
PrintWriter STmsgTo[] = new PrintWriter[3];
DataInputStream[] STfileFrom = new DataInputStream[3];
// for UserThread of client
BufferedReader UTmsgFrom[] = new BufferedReader[3];
PrintWriter UTmsgTo[] = new PrintWriter[3];
DataOutputStream[] UTfileTo = new DataOutputStream[3];
for(int i=0; i<3; i++) {
// connecting initially
System.out.println("Waiting for client "+i);
Socket client = welcome.accept();
PrintWriter send = new PrintWriter(client.getOutputStream(),true);
BufferedReader receive = new BufferedReader(new InputStreamReader(client.getInputStream()));
// sending serial number
send.println(Integer.toString(i));
// sending ports for thread sockets
send.println(Integer.toString(startSTport+i));
send.println(Integer.toString(startUTport+i));
// accepting sockets
tmpSocket = new ServerSocket(startSTport+i);
STsocket = tmpSocket.accept();
tmpSocket = new ServerSocket(startUTport+i);
UTsocket = tmpSocket.accept();
// creating communications
STmsgFrom[i] = new BufferedReader(new InputStreamReader(STsocket.getInputStream()));
STmsgTo[i] = new PrintWriter(STsocket.getOutputStream(),true);
STfileFrom[i] = new DataInputStream(STsocket.getInputStream());
UTmsgFrom[i] = new BufferedReader(new InputStreamReader(UTsocket.getInputStream()));
UTmsgTo[i] = new PrintWriter(UTsocket.getOutputStream(),true);
UTfileTo[i] = new DataOutputStream(UTsocket.getOutputStream());
System.out.println("Connected client "+i);
}
ClientThread ct0 = new ClientThread(0,STmsgFrom,STmsgTo,STfileFrom,UTmsgFrom,UTmsgTo,UTfileTo);
ClientThread ct1 = new ClientThread(1,STmsgFrom,STmsgTo,STfileFrom,UTmsgFrom,UTmsgTo,UTfileTo);
ClientThread ct2 = new ClientThread(2,STmsgFrom,STmsgTo,STfileFrom,UTmsgFrom,UTmsgTo,UTfileTo);
ct0.start();
ct1.start();
ct2.start();
System.out.println("Server Stup Complete!");
}
}
class ClientThread extends Thread {
String msg;
int cid;
BufferedReader[] STmsgFrom;
PrintWriter[] STmsgTo;
DataInputStream[] STfileFrom;
BufferedReader[] UTmsgFrom;
PrintWriter[] UTmsgTo;
DataOutputStream[] UTfileTo;
public ClientThread(int cid,BufferedReader[] STmsgFrom,PrintWriter[] STmsgTo,DataInputStream[] STfileFrom,BufferedReader[] UTmsgFrom,PrintWriter[] UTmsgTo,DataOutputStream[] UTfileTo) {
this.cid=cid;
this.STmsgFrom=STmsgFrom;
this.STmsgTo=STmsgTo;
this.STfileFrom = STfileFrom;
this.UTmsgFrom=UTmsgFrom;
this.UTmsgTo=UTmsgTo;
this.UTfileTo = UTfileTo;
}
#Override
public void run() {
while(true) {
try {
// receiving request from receiver UserThread
msg = UTmsgFrom[cid].readLine();
if(msg.equals("get list")) { // receiver requested for file list
System.out.println("Request from "+cid+": "+msg);
for(int i=0; i<3; i++) {
if(i==cid) continue;
// sending request to sender ServerThread
STmsgTo[i].println("give list");
System.out.println("Request to "+i);
// receive file count from sender ServerThread
int cnt = Integer.parseInt(STmsgFrom[i].readLine());
System.out.println(i+" has files: "+cnt);
// sending source identity to receiver UserThread
UTmsgTo[cid].println(Integer.toString(i));
// send file count back to receiver UserThread
UTmsgTo[cid].println(Integer.toString(cnt));
// get and send file names to receiver
for(int j=0; j<cnt; j++) {
msg = STmsgFrom[i].readLine();
UTmsgTo[cid].println(msg);
}
}
} else if(msg.equals("get file")) {
// get source id and filename
int source = Integer.parseInt(UTmsgFrom[cid].readLine());
String fileName = UTmsgFrom[cid].readLine();
//System.out.println("get source id and filename");
// ask source about file
STmsgTo[source].println("give file");
STmsgTo[source].println(fileName);
boolean fileOk = Boolean.parseBoolean(STmsgFrom[source].readLine());
//System.out.println("ask source about file");
// telling receiver about file status
UTmsgTo[cid].println(Boolean.toString(fileOk));
//System.out.println("telling receiver about file");
if(fileOk) {
// get copy request from receiver
msg = UTmsgFrom[cid].readLine();
//System.out.println("receiver copy command");
if(msg.equals("yes copy")) {
System.out.println("Copying \'"+fileName+"\' from "+source+" to "+cid);
// tell sender to copy
STmsgTo[source].println("yes copy");
//System.out.println("tell sender copy command");
// copy from SENDER
// get file size
int FILE_SIZE = Integer.parseInt(STmsgFrom[source].readLine());
byte[] fileBytes = new byte[FILE_SIZE];
System.out.println("Get file size "+FILE_SIZE);
// get file data
int portion = STfileFrom[source].read(fileBytes,0,fileBytes.length);
int position = portion;
do {
portion = STfileFrom[source].read(fileBytes,position,fileBytes.length-position);
if(portion>=0) {
position += portion;
}
System.out.println("position = "+position);
} while(position<FILE_SIZE);
System.out.println("Get file data "+position);
// copy to RECEIVER
// send file size
UTmsgTo[cid].println(Integer.toString(FILE_SIZE));
//System.out.println("send file size");
// send file data
UTfileTo[cid].write(fileBytes,0,position);
UTfileTo[cid].flush();
//System.out.println("send file data");
System.out.println("Copying \'"+fileName+"\' complete");
} else {
// tell sender to ignore copy process
STmsgTo[source].println("no copy");
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
Client:
package client;
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) throws Exception {
String msg;
InetAddress inetAddress = InetAddress.getLocalHost();
String[] allPaths= {"H:\\Study\\Lab\\Network\\Assingment 2 and lab of 5 july\\Assignment\\files\\client_1_folder",
"H:\\Study\\Lab\\Network\\Assingment 2 and lab of 5 july\\Assignment\\files\\client_2_folder",
"H:\\Study\\Lab\\Network\\Assingment 2 and lab of 5 july\\Assignment\\files\\client_3_folder"};
// connecting to welcome socket
Socket server = new Socket(inetAddress,6000);
BufferedReader receive = new BufferedReader(new InputStreamReader(server.getInputStream()));
BufferedReader receiveUser = new BufferedReader(new InputStreamReader(System.in));
PrintWriter send = new PrintWriter(server.getOutputStream(),true);
// receiving serial number
int cid = Integer.parseInt(receive.readLine());
// receiving port numbers for thread sockets
int STport = Integer.parseInt(receive.readLine());
int UTport = Integer.parseInt(receive.readLine());
// connecting sockets
Socket STsocket = new Socket(inetAddress,STport);
Socket UTsocket = new Socket(inetAddress,UTport);
System.out.println("Connected to the server.\nSerial: "+cid+"\nFolder path: "+allPaths[cid]);
ServerThread st = new ServerThread(allPaths[cid],STsocket);
UserThread ut = new UserThread(cid,allPaths[cid],UTsocket);
st.start();
ut.start();
}
}
class UserThread extends Thread {
int cid;
String msg,folderPath;
BufferedReader msgFromServer,fromUser;
PrintWriter msgToServer;
// for file
DataInputStream fileFromServer;
BufferedOutputStream writeFile;
public UserThread(int cid,String folderPath,Socket socket) {
try {
this.cid = cid;
this.folderPath = folderPath;
fromUser = new BufferedReader(new InputStreamReader(System.in));
msgFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msgToServer = new PrintWriter(socket.getOutputStream(),true);
// for file
fileFromServer = new DataInputStream(socket.getInputStream());
} catch(Exception ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
//System.out.println("User Thread Started!");
while(true) {
try {
msg = fromUser.readLine();
if(msg.equals("get list")) {
// sending request to server
msgToServer.println("get list");
// getting file list from server
System.out.println("-------------------------------------------");
for(int i=0; i<2; i++) {
// getting source id
int source = Integer.parseInt(msgFromServer.readLine());
System.out.println("Source: "+source);
int cnt = Integer.parseInt(msgFromServer.readLine());
System.out.println("Files: "+cnt);
System.out.println("--------------");
for(int j=0; j<cnt; j++) {
msg = msgFromServer.readLine();
System.out.println(msg);
}
System.out.println("-------------------------------------------");
}
} else if(msg.equals("get file")) {
// GETTING A FILE
int source;
while(true) {
System.out.println("File Source: ");
try {
source = Integer.parseInt(fromUser.readLine());
if(0<=source && source<=2 && source!=cid) {
break;
} else {
System.out.println("Error: File source invalid. Try again.");
}
} catch(Exception ex) {
System.out.println("Error: File source invalid. Try again.");
}
}
System.out.println("File Name: ");
String fileName = fromUser.readLine();
// send request to server to check file
msgToServer.println("get file");
msgToServer.println(Integer.toString(source));
msgToServer.println(fileName);
// receiving file status
boolean fileOk = Boolean.parseBoolean(msgFromServer.readLine());
if(!fileOk) {
System.out.println("Error: File does not exist at source.");
} else {
System.out.println("File is available!!");
System.out.println("Want to copy \'"+fileName+"\'? (y/n)");
msg = fromUser.readLine();
if(msg.equals("y")||msg.equals("Y")) {
// tell server to copy file
msgToServer.println("yes copy");
// COPY PROCESS
// get file size
int FILE_SIZE = Integer.parseInt(msgFromServer.readLine());
System.out.println("File size: "+FILE_SIZE+" bytes.");
byte[] fileBytes = new byte[FILE_SIZE];
// get file data
int portion = fileFromServer.read(fileBytes,0,fileBytes.length);
int position = portion;
do {
portion = fileFromServer.read(fileBytes,position,fileBytes.length-position);
if(portion>=0) {
position += portion;
}
System.out.println("position = "+position);
} while(position<FILE_SIZE);
System.out.println("Total "+position+" bytes received.");
// write file data
File file = new File(folderPath + "\\" + fileName);
writeFile = new BufferedOutputStream(new FileOutputStream(file));
writeFile.write(fileBytes,0,position);
writeFile.flush();
writeFile.close();
System.out.println("Copying complete.");
} else {
msgToServer.println("no copy");
}
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
class ServerThread extends Thread {
String msg,folderPath;
BufferedReader msgFromServer;
PrintWriter msgToServer;
// for file
DataOutputStream fileToServer;
BufferedInputStream readFile;
public ServerThread(String folderPath,Socket socket) {
try {
this.folderPath = folderPath;
msgFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
msgToServer = new PrintWriter(socket.getOutputStream(),true);
// for file
fileToServer = new DataOutputStream(socket.getOutputStream());
} catch(Exception ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
//System.out.println("Server Thread Started!");
while(true) {
try {
msg = msgFromServer.readLine();
if(msg.equals("give list")) {
//System.out.println("Request from server: "+msg);
File folder = new File(folderPath);
File[] fileList = folder.listFiles();
int cnt = fileList.length;
//System.out.println("Files: "+cnt);
// give file count back to server
msgToServer.println(Integer.toString(cnt));
// give file list back to server
for(int i=0; i<cnt; i++) {
msgToServer.println(fileList[i].getName());
}
} else if(msg.equals("give file")) {
// receive file name
String fileName = msgFromServer.readLine();
// telling server about file status
File file = new File(folderPath + "\\" + fileName);
boolean fileOk = file.exists();
msgToServer.println(Boolean.toString(fileOk));
if(fileOk) {
// getting copy request
msg = msgFromServer.readLine();
if(msg.equals("yes copy")) {
// COPY PROCESS
// send file size
int FILE_SIZE = (int)file.length();
msgToServer.println(Integer.toString(FILE_SIZE));
// read file data
readFile = new BufferedInputStream(new FileInputStream(file));
byte[] fileBytes = new byte[FILE_SIZE];
readFile.read(fileBytes,0,fileBytes.length);
readFile.close();
// send file data
fileToServer.write(fileBytes,0,fileBytes.length);
fileToServer.flush();
} // otherwise end of conversation
}
}
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
I am aware that I have done some unnecessary things like giving different ports to all the different sockets. Ignore them if they are not the reason of my problem.
ServerSocket.accept() is blocking, you can't call it twice from the same thread.
Every ServerSocket must run in its own thread.
i'm trying to write a program which uses sockets to send and receive an image.
The Java source should run on android devices. But the class TCP also works on normal java applications.
To be hornest it is just a feature of my whole program.
First of all i want to share my source codes:
Java :
Async (to use it on newer Versions of android >5.**)
class Async extends AsyncTask<String, TCPClient, String> {
#Override
protected String doInBackground(String... args) {
TCPClient cp = new TCPClient();
try {
if (args[1].equals("remote"))
cp.TCPSend(args[0]);
else {
cp.TCPrecv();
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
}
TCP Client:
class TCPClient
{
public void TCPSend(String sentence) throws IOException
{
String modifiedSentence;
Socket clientSocket = new Socket("192.168.0.14", 1334);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(sentence + '\n');
modifiedSentence = inFromServer.readLine();
System.out.println("FROM SERVER: " + modifiedSentence);
clientSocket.close();
}
public Bitmap TCPrecv() throws IOException
{
Socket clientSocket = new Socket("192.168.0.14", 1331);
DataInputStream dis;
dis = new DataInputStream(clientSocket.getInputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String size_pic = inFromServer.readLine();
int bytesize=Integer.parseInt(size_pic);
int bytesRead=0;
byte[] pic = new byte[bytesize];
int read=0;
while(read < bytesize && !(bytesRead ==-1)) {
bytesRead = dis.read(pic, 0, 10239);
read += bytesRead;
}
return BitmapFactory.decodeByteArray(pic, 0, pic.length);
}
}
This programm reads a image as a ByteArray. It works for 36/37 packets. Don't matter which size of packets i use. The last packet get lost.
I write some own codes of C Servers but the best code i found on this forum.
The Code snipe contains client and server functions and it works perfect.
But the connection of the the Java Programm works not for all packets.
C Code :
void error(const char *msg)
{
perror(msg);
exit(1);
}
int send_image(int socket){
FILE *picture;
int size, read_size, stat, packet_index;
char send_buffer[10240], read_buffer[256];
packet_index = 1;
picture = fopen("../MR.PNG", "r");
printf("Getting Picture Size\n");
if(picture == NULL) {
printf("Error Opening Image File"); }
fseek(picture, 0, SEEK_END);
size = ftell(picture);
fseek(picture, 0, SEEK_SET);
printf("Total Picture size: %i\n",size);
//Send Picture Size
printf("Sending Picture Size\n");
char *ptr=(char *) malloc(500);
sprintf(ptr,"%d",size);
strcat(ptr,"\n");
write(socket,ptr,20);
//Send Picture as Byte Array
printf("Sending Picture as Byte Array\n");
/* do { //Read while we get errors that are due to signals.
stat=read(socket, &read_buffer , 255);
printf("Bytes read: %i\n",stat);
} while (stat < 0);*/
printf("Received data in socket\n");
printf("Socket data: %c\n", read_buffer);
while(!feof(picture)) {
//while(packet_index = 1){
//Read from the file into our send buffer
read_size = fread(send_buffer, 1, sizeof(send_buffer)-1, picture);
//Send data through our socket
do{
stat = write(socket, send_buffer, read_size);
}while (stat < 0);
printf("Packet Number: %i\n",packet_index);
printf("Packet Size Sent: %i\n",read_size);
printf(" \n");
printf(" \n");
packet_index++;
//Zero out our send buffer
bzero(send_buffer, sizeof(send_buffer));
int send_image(int socket){
FILE *picture;
int size, read_size, stat, packet_index;
char send_buffer[10240], read_buffer[256];
packet_index = 1;
picture = fopen("../MR.PNG", "r");
printf("Getting Picture Size\n");
if(picture == NULL) {
printf("Error Opening Image File"); }
fseek(picture, 0, SEEK_END);
size = ftell(picture);
fseek(picture, 0, SEEK_SET);
printf("Total Picture size: %i\n",size);
//Send Picture Size
printf("Sending Picture Size\n");
write(socket, (void *)&size, sizeof(int));
//Send Picture as Byte Array
printf("Sending Picture as Byte Array\n");
do { //Read while we get errors that are due to signals.
stat=read(socket, &read_buffer , 255);
printf("Bytes read: %i\n",stat);
} while (stat < 0);
printf("Received data in socket\n");
printf("Socket data: %c\n", read_buffer);
while(!feof(picture)) {
//while(packet_index = 1){
//Read from the file into our send buffer
read_size = fread(send_buffer, 1, sizeof(send_buffer)-1, picture);
//strcat(send_buffer,"\n");
//Send data through our socket
do{
stat = write(socket, send_buffer, read_size);
}while (stat < 0);
printf("Packet Number: %i\n",packet_index);
printf("Packet Size Sent: %i\n",read_size);
printf(" \n");
printf(" \n");
packet_index++;
//Zero out our send buffer
bzero(send_buffer, sizeof(send_buffer));
}
}
}
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
char contentbuffer[255];
struct sockaddr_in serv_addr, cli_addr;
int n;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = 1331;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while(1)
{
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
int i=0;
send_image(newsockfd);
}
close(newsockfd);
close(sockfd);
return 0;
}
I dont understand why this code 2 times works without problems. But without any changes the last bytes get lost... :-/
Sorry, my english is very badly. But i realy need help. It is so frustrating to debug an program without the knowlege to understand what the problem is.
Sorry again. I have trouble with the code snipes system. It want work on Class TCP Client.
Thank for your attention.
MFG Neks
Edit: After some comments i'm modified my Java Code. Now the same code works on a real Java Programm with Java EE IDE. This program works fine. But the same code want work on Android. I don't understand why. I can post pics of the debugging sessions.
package com.vib;
import java.io.;
import java.net.;
class NewTcpClient {
#SuppressWarnings("resource")
public void TCPrecv() throws IOException {
Socket clientSocket = new Socket("192.168.0.14", 1331);
DataInputStream dis;
dis = new DataInputStream(clientSocket.getInputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String size_pic = inFromServer.readLine();
int bytesize = Integer.parseInt(size_pic);
int bytesizeread = 10239;
int bytesRead = 0;
byte[] pic = new byte[bytesize];
int read = 0;
int count=0;
while (read < bytesize)
{
bytesRead = dis.read(pic, 0, bytesizeread);
read += bytesRead;
count++;
}
clientSocket.close();
System.out.println(pic);
}
public static void main(String argv[]) throws Exception {
NewTcpClient tcp = new NewTcpClient();
tcp.TCPrecv();
}
}
I don't understand whats going on... i uses this programm on normal IDE now for 3 houres... now it want work... without any changes. How can i debugg something so mystil? ^^
After a break of 2 hours the program works fine. What can be a reason for this bug.
I have two projects; one for my server and one for my client, I am able to send images to the server with ease. But I am wondering how would you be able to download that image you just sent to the server back to the client when I press the download button I have created on my client GUI? My code is written in java.
Many Thanks
This is my serverhandler
String fileName;
fileName = "RecievedImageoutreach1.jpg";
DataOutputStream dout = new DataOutputStream(sock.getOutputStream());
//Coding for image transfer
int flag=0,i;
String extn="";
for(i=0; i<fileName.length(); i++)
{
if(fileName.charAt(i)=='.' || flag==1)
{
flag=1;
extn += fileName.charAt(i);
}
}
if(extn.equals(".jpg") || extn.equals(".gif"))
{
try{
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
dout.writeUTF(fileName);
byte[] readData = new byte[1024];
while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
}
And this is my client
public void download() throws IOException {
// Get input from the server
DataInputStream dis = new DataInputStream (sock.getInputStream());
String str,extn = "";
str = dis.readUTF();
int flag=0,i;
for(i=0;i<str.length();i++)
{
if(str.charAt(i)=='.' || flag==1)
{
flag=1;
extn+=str.charAt(i);
}
}
//**********************reading image*********************************//
if(extn.equals(".jpg") || extn.equals(".gif"))
{
File file = new File("Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
while((i = dis.read(readData)) != -1)
{
fout.write(readData, 0, i);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
}
fout.flush();
fout.close();
}
}
But when run nothing occurs? i have linked the client method to run when a button is clicked.
I would do something like this:
//Server Handler
File file = new File(fileName);
FileInputStream fin = new FileInputStream(file);
// dout.writeUTF(fileName);
byte[] readData = new byte[1024];
fin.read(readData);
fin.close();
dout.write(readData, 0, readData.length);
dout.flush();
/* while((i = fin.read(readData)) != -1)
{
dout.write(readData, 0, i);
}*/
//ta.appendText("\nImage Has Been Sent");
dout.flush();
fin.close();
}catch(IOException ex)
{System.out.println("Image ::"+ex);}
}
//Receiving image
if(extn.equals(".jpg") || extn.equals(".gif"))
{
//give path to new file
File file = new File(".//Downloaded"+str);
FileOutputStream fout = new FileOutputStream(file);
//receive and save image from client
byte[] readData = new byte[1024];
int offset =0;
while((i = dis.read(readData,0,readData.length-offset)) != -1){
offset += i;
}
fout.write(readData, 0, readData.length);
if(flag==1)
{
ta.append("Image Has Been Downloaded");
flag=0;
}
fout.flush();
fout.close();
}
}
Assuming that you would have to provide file name and then press download button. So on server side convert the image into byte stream and write over the connection socket. On client side recieve bytes into buffer and then create FileOutputStream providing the directory for output. Write the recieved bytes onto the file using the outputstream created.
This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 7 years ago.
i'm trying to send some files from a server to some clients in android.
i receive the file through a bufferedInputStream by read(byte[] array,int startIndex,int arraySize) method that returns the number of bytes it can read and -1 if there is no input to read.
i receive the file in a loop and i must go out of the loop when my file finishes, but the read method is not returns -1 and just waiting for more input to read :/
so my code is blocking....
i tried to send the file size from the server and when receiving it,and subtract number reads byte from it every time i read a buffer, so when this number hits 0 means i received all file and should break the loop, BUT in some files it doesn't hit 0 as if some part of my file is not sent :| but when i do the same thing in the server side (subtract the sent part from the early file size) it always hit 0 ....
SO my problem is how to know i read all file to break the reading loop :(
similar question
my question is differ from this link because i done the suggested answer but the remaining file size is NOT reach 0 in some files and i dont know why
here is my code for send the file in sever side:
public void sendFile(File file){
BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bos = new BufferedOutputStream(outputStream);
byte[] temp = new byte[2 * 1024];
int length ;
int fileSize=(int)file.length();
Log.d("file size",Integer.toString(fileSize));
//int sendSize =0;
while (true){
length = bis.read(temp,0,temp.length);
if(length == -1) break;
bos.write(temp,0,length);
fileSize-=length;
assert (fileSize >=0 );
//if(fileSize==0)break;
}
// outputStream.write(-1);
bos.flush();
Log.d("File ", "Send finisheeed!");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}finally {
try {
bis.close();
//bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and here is the part of client code that receives the file :
Log.d("File name is", fileName);
// File outFile = new File("/storage/sdcard0/m2app" + fileName);
// outFile.createNewFile();
bos = new BufferedOutputStream(new FileOutputStream("/storage/sdcard0/m2app" + fileName));
byte[] temp = new byte[2 * 1024];
int length = 0;
while (true)
{
length = bis.read(temp,0,temp.length);
fileLength -= length;
// Log.d("read",Integer.toString(fileLength) );
if(length == -1 || fileLength == 0 ) {
// if(temp[length-1] == -1){
// bos.write(temp,0,length-1);
// bos.flush();
// Log.d("file","recived!!!!!!!!!!");
break;
}
if(fileLength < 4000 && bis.available() == 0)
break;
bos.write(temp,0,length);
bos.flush();
/*if(fileLength == 0){
Log.d("file","0 shod");
break;
}*/
}
while (fileLength > 0 )
fileLength-=bis.skip(fileLength);
// inputStream.reset();
bos.close();
Log.d("File " , "Receiving finisheeeeeeeeeddddd!!!");
isFile = false;
You need to close the output stream in the file sender for the input stream in the file receiver to get the EOF.
Using try-with-resources you can dramatically simplify the code:
public void sendFile(File file) {
try(BufferedOutputStream bos = new BufferedOutputStream(outputStream);
FileInputStream fis = new FileInputStream(file));
BufferedInputStream bis = new BufferedInputStream(fis)) {
byte[] temp = new byte[64 * 1024];
int length ;
int fileSize=(int)file.length();
Log.d("file size",Integer.toString(fileSize));
while ((bis.read(temp,0,temp.length) != -1){
bos.write(temp,0,length);
}
Log.d("File ", "Send finished!");
} catch (IOException e) {
e.printStackTrace();
}
}
I am writing a server and client file transfer module and I wanted to know If it is possible to send the file info along with file itself.Particularly I need file names and folder structure of the file on server sent to the client.
Ex. if I have c:\abc\efg\a.txt on server I want .\abc\efg\a.txt on client.
this is the code I'm using :
Server Side File Send:
Socket clientSocket=new Socket("Some IP",12345);
OutputStream out=clientSocket.getOutputStream();
FileInputStream fis=new FileInputStream(file);
int x=0;
byte[] b = new byte[4194304];
while(true){
x=fis.read(b);
if(x==-1)break;
out.write(b);
}
out.close();
Client Listener:
try {
ServerSocket ss=new ServerSocket(12345);
while(true){
final Socket client = ss.accept();
new Thread(new Runnable() {
#Override
public void run() {
try{
InputStream in = client.getInputStream();
FileOutputStream fos = new FileOutputStream("rec.txt");
int x=0;
byte[] b = new byte[4194304];
while(true){
x=in.read(b);
if(x==-1)break;
fos.write(b);
}
fos.close();
}
catch(Exception e){
}
}
}).start();
}
} catch (Exception e) {
}
You need to send the file path then the file name, use a 64 byte buffer to do that, once you get the path and name you read the file contents.
For example:
// Server
try
{
Socket clientSocket=new Socket("Some IP",12345);
OutputStream out=clientSocket.getOutputStream();
FileInputStream fis=new FileInputStream(file);
byte[] info = new byte[64];
int len = file.getPath().length();
info = file.getPath().getBytes();
for (int i=len; i < 64; i++) info[i]=0x00;
out.write(info, 0, 64);
len = file.getName().length();
info = file.getName().getBytes();
for (int i=len; i < 64; i++) info[i]=0x00;
out.write(info, 0, 64);
int x;
byte[] b = new byte[4194304];
while((x=fis.read(b)) > 0)
{
out.write(b, 0, x);
}
out.close();
fis.close();
}
catch (Exception e)
{
e.printStackTrace();
}
// Client
try
{
InputStream in = client.getInputStream();
FileOutputStream fos = new FileOutputStream("rec.txt");
byte[] path = new byte[64];
in.read(path, 0, 64);
byte[] name = new byte[64];
in.read(name, 0, 64);
int x=0;
byte[] b = new byte[4194304];
while((x = in.read(b)) > 0)
{
fos.write(b, 0, x);
}
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
Send a header first with all information you need, then a separator (e.g. 0) then the file content. Server side reads the header till the separator then the content.
I have done this before. I used DataOutputStream at the server and DataInputStream at the client.
I used this protocol:
1. send the file name .writeUTF(fileName);
2. send the file size .writeLong(fileSize);
3. send the file .writeBytes(byteArray); // this is done inside a for loop since file size can be too big to be put into memory at once. Both the server and client size will use fileSize to determine when to stop.
The client side will use the same protocol but instead of "write", it will be "read".
Zip
1. file
2. Information about file
Send it )