I'm trying to use openssl bio to perform FTP STOR operation. Most of the time it works perfectly, but sometimes it only sends partial data. So the logic goes like this:
1. authentication and passive mode selection
2. open data connection
3. write data
4. QUIT
All operations should be performed synchronously. The data writing function does this:
while (written < toWrite && n > 0) {
n = BIO_write(bio, message.c_str() + written, toWrite - written);
written += n;
}
After this loop, written == toWrite and n > 0, so it would indicate that the write was completed successfully. However, the file is truncated. When I view the operation in wireshark, I can notice that QUIT operation is sent right after the first chunk of data is transferred. Client also continues sending some data chunks after QUIT command. Does anyone have a clue how that is possible?
EDIT: If there's a short delay (e.g. sleep) between writing data and QUIT, it works perfectly.
I found out the problem. I did not wait for the response on control socket between closing the data connection and sending QUIT. This question was helpful for finding the answer.
Related
I am developing an application in WinCE7. The application includes a serial com port and file IO operations. There is an embedded device connected the serial port. I need to check the status of inputs on the device and save their details in file. Lets say, if input 1 is high then I need to write Input 1 HIGH on the serial port, and save the same in file.
Now to write data in file I am using fprintf & fopen functions. Code looks like below:
main()
{
// some code to initialize serial port
FILE * fp;
fp= fopen ("Logs.txt", "w+"); //-------> create a file named as Logs.txt
while(1)
{
if(Input1 == TRUE)
{
serialPort.Send("Input 1 HIGH");
fprintf(fp,"%s","Input 1 HIGH"); //-------> saving data in file
}
if(Input2 == TRUE)
{
serialPort.Send("Input 2 HIGH");
fprintf(fp,"%s","Input 2 HIGH"); //-------> saving data in file
}
//same goes for rest of the inputs
}
fclose(fp); //----------> closing the file
}
Now after writing data to the file using fprintf, we need to use fclose() to close the file. But as I have to continuously monitor the input status I have used while(1) due to which my control doesn't reaches at fclose(fp). Thus the file is not closed and it becomes corrupted. When I open the file to see the saved data it gave me below error:
How can I properly use flcose() and fprintf() to write data in file.?
There is nothing wrong with opening log file and closing each time you want to do the logging. It might cause problems if your while loop is being executed with very high frequency - it may slow down your application. This is why you should consider a way to somehow close your application, now as I understand you copy your log file while your application is being executed - this can cause all sort of problems - among others that your file will be corrupted.
btw. you can also use windows-ce native logging api like: CeLog, see here:
https://msdn.microsoft.com/en-us/library/ee479601.aspx
https://msdn.microsoft.com/en-us/library/ee488587.aspx
When would your loop start, and when would it end? I mean, not programatically, but theoretically? The simplest thing seems to be to modify the while condition. As of now, it will be endlessly stuck in the while loop!
Lets assume that your program is running, and it keeps on running for as long as your device remains connected. So you need to monitor some message or look for some event that signifies that the device has disconnected or stopped (or whatever is appropriate). This event or situation can be used as a flag (for eg., TRUE while the device is connected and active, FALSE when the device is disconnected or inactive) and then use that as a condition to open/write/close the file.
Further more, instead of a loop, you could use a timer or a periodic event to poll your device input. You can adjust your polling rate as high as you like, depending on the accuracy of your timer. This will ensure that your code doesn't get stuck in a loop. Say, you call your function to monitor the input at every timer tick. So each time the tick event fires, the input will be read. And you can check the condition of the device's connection before calling the polling function.
the flow would go something like:
Start->Device connected, flag TRUE->fOpen->Start timer
=>timer tick->flag == TRUE?->poll device->write to file=> (repeats for each tick unless the below scenario happens.)
Device disconnected, flag FALSE
=>timer tick->flag == TRUE? NO->fClose->Stop timer->Stop
This would assume that you had some way of detecting the device connect/active vs disconnect/inactive situations. Maybe the device SDK has some form of message or event that signifies this.
New to Socket Programming. I was making a HTTP server. In the persistent connection, I keep the socket open after the server has sent the first file (1 MB text file) for the 1st HTTP request from the client. After that the server and client programs just sit idle. I have searched a lot and found that recv() keeps looking for data on the socket until the socket connection closes from the server side.
What Should I do in case of a persistent connection?
I am reading a file at the client side (File contains many lines. On each line there's just a file name, that is to be fetched from the server via a persistent connection)
Part of Server code which send the file requested:
while((bytesread = fread(filecontent,sizeof(char), 1024, fp))>0)
{
printf("Bytes Read:%d File Content:%s\n",bytesread,filecontent);
if((n = send(*newsockfd, filecontent, 1024,0))<0)
{
error("SERVER Error: Failed to Write File to Socket");
break;
}
bzero(filecontent,1024);
}
Part of client code where I read the file that has been sent by the server:
for(;;)
{
n=recv(socketfd, buffer, 1024,0);
printf("%d\n",n);
if(n>0)
{ printf("\n in while for reading the file for n bytes %d \n",n);
printf("Response:\n%s",buffer);
}
else if(n<0)
{
disperror("Error reading from socket");
}
if(n==0)
break;
}
Have spent a lot of time. Could not get what to do...
Your client-server protocol is insufficient. The server sends all the bytes of the input file (and more, because you hard-coded 1024 instead of using bytesread). But how should the client understand when the file is complete?
One easy solution is to have the server begin each transmission with the file size. You can simply send a uint64_t (not int because it must be a fixed size on all platforms). That number will represent the total bytes to follow (i.e. the file size). You can get the file size using fseek in the usual way (SEEK_END then ftell or similar).
Then, once your client has received the specified number of bytes, it can break out of the loop.
continues reading even though socket is empty
'Socket is empty' is meaningless. It is either open or closed. In this case it is still open, so your code keeps reading. It will only stop when the peer closes the connection.
If you're going to implement HTTP you need a good working knowledge of RFC 2616, especially the parts relating to content length. Your code doesn't begin to address that currently, and it's too brodpad a topic to cover here. Uffice it to say that keepalive and reading a socket to end of stream are mutually inconsistent.
NB if you get an error reading a socket other than EAGAIN/EWOULDBLOCK you should exit the loop, and you should also print the real error, not some message of your own devising.
NB (2) You don't need to zero the buffer.
NB (3) The correct way to print the buffer is printf("%.*s", n, buffer), but only if n > 0.
I am trying to write a Matlab code that will receive data from an outside c program and graph it. The data is in text format. In my past attempts every time the connection is made, but no message is received by the matlab program even though I can verify that is was sent. Basically I am looking for an answer on the correct way in Matlab to retrieve data from a TCP connection that was sent from a c program.
function tcp_testing()
t = tcpip('localhost',7220,'NetworkRole','server')
% Set size of receiving buffer, if needed.
set(t, 'InputBufferSize', 30000);
% Open connection to the server.
fopen(t);
% Transmit data to the server (or a request for data from the server).
fprintf(t, 'GET /');
% Pause for the communication delay, if needed.
pause(1)
% Receive lines of data from server
while (get(t, 'BytesAvailable') > 0)
t.BytesAvailable
DataReceived = fscanf(t)
end
end
I am a C newbie learning sockets. I wrote a client-server program to receive a file and write it to another file.
The program itself works fine - the file is read by server properly and the client receives it in full, but the client does not exit after receiving all the data.
How would the client know when the entire file is received and how do I make it exit? Following is my client snippet.
Note: I added the condition while (data > 0) as a part of this attempt. Please correct this if wrong.
#define BUFFER 2048
char recived_data[BUFFER];
bzero(recived_data, BUFFER);
FILE *new_file = fopen(“Test.jpg”, “w”);
int data;
do {
data = recv(sockfd, recived_data, BUFFER, 0);
fwrite(recived_data, 1, sizeof(recived_data), new_file);
} while (data > 0);
Your server should close the socket after the whole file content has been sent. This would cause your recv function to return zero and end the client's receive loop.
If you want to keep the connection for some reason, then you would need to send some additional information to the client first (e.g. file length) - so the client knows when one file ends and (potentially) another begins. I'm not sure if you are interested in that, though.
The sender can send the file size before sending the file. The receiver can then receive the file size (say 4 bytes), then call recv() until the full file size has been received.
Let me start out by saying that this is a homework assignment for an operating systems class and I am not a programmer, especially not in C. I've been at this for a week now and I am simply stuck and I need help. I have to create TCP client and server applications where linux commands are typed into the client, executed on the server and the output is redirected back to the client. I understand the concept and I have it 90+% working. Commands like "ls", "ls -lpq", "cat somefile", "man somecommand" all work fine. Where I run into trouble is with commands that do not return any information like "mkdir newdir" (if the directory already exists it works fine because I get a response). This is all new to me but it seems to me that my problem is with the servers recv command blocking because there is no information to receive. I don't know how to get past this, I have been working this one issue for a week. I'm running out of time and I also have to implement file upload and download and I don't know where to begin there but I can't even start to work on that until I get past this issue.
Thanks
// this is where I think the problem is
while ((rcvd_bytes = recv(sock_fd, recv_str, sizeof(recv_str), 0)) > 0 ) {
// Zero out the inputCopy buffer
memset(&inputCopy, 0, sizeof(inputCopy)+1);
// Copy the recv_str into a new string so that
// we can work with it.
strcpy(inputCopy, recv_str);
argcount = parsecommand(inputCopy, args);
//Send the message back to client
dup2(sock_fd, 1);
if((status = forkAndExecute(args)) != 0) {
//printf("Command %s returned %d.\n", args[0], status);
}
// as a test is I uncomment the following line mkdir newdir
// returns but the following commands are messed up - as I expect.
//printf("\n");
memset(&recv_str, 0, sizeof(recv_str)+1);
fflush(stdout);
}
if(rcvd_bytes == 0) {
puts("Client disconnected");
fflush(stdout);
}
else if(rcvd_bytes == -1) {
perror("recv failed");
exit(0);
}
Sounds like you need to use select .
if(select(fdmax+1, &my_fdset, 0, 0, NULL) > 0) // there is data available to be read
recv(...)
where fdmax is the largest file descriptor (select wants that +1) and my_fdset is a file descriptor set that you add file descriptors to using FD_SET(sockfd, &my_fdset);.
This will only receive when there is data available. Hope that helps.
EDIT :
I asked a similar question when I was writing a simple client/server program to send/recv strings over a TCP socket. I posted the code that I ended up using on that thread here. Mine is different in that I wanted one program to send and recv but if you look at my sender or receiver functions, you may be able to adapt something to make your program do what you want.
Given your problem description, my suspicion is the client code rather than the server code -- or, actually, the protocol you've implicitly created between the two.
It looks like you're just sending the output of the command directly back to the client by using dup2 to point standard output at the socket. Presumably, the client then reads from the socket to get the output from the command? What does the client do when it sends a command to the server and then gets no reply? A command like mkdir will send nothing back. Is it waiting forever for the server to send command output?
In general, for a synchronous client/server protocol (one where the client sends a command and the server sends a response before the client sends another command), you have to agree on a protocol between the client and the server to clearly indicate when the server is done sending data back and the client should send its next command. You may need to add some way for the server to tell the client that the command completed but sent no output.