Not able to receive File name in server sent by client - sockets

I am trying to write a simple socket program which reads a file name in client and sends it to the server. The contents of file are sent to the Client back if present. The client and server are able to successfully able to connect but when I read a file name I don't get any output(program doesn't terminates). Please tell me what is going wrong.
server.c
int main()
{
int create_socket,new_socket,fd,addlen,n;
int bufsize=1024;
char *buffer=malloc(bufsize);
char fname[255];
struct sockaddr_in address;
//printf("program");
if((create_socket=socket(AF_INET,SOCK_STREAM,0))>0)
printf("socket created");
address.sin_family=AF_INET;
address.sin_port=htons(15000);
address.sin_addr.s_addr=INADDR_ANY;
if(bind(create_socket,(struct sockaddr*)&address,sizeof(address))==0)
printf("socket binded");
while(1)
{
printf("Inside while loop");
listen(create_socket,3);
addlen=sizeof(struct sockaddr_in);
if(new_socket=accept(create_socket,(struct sockaddr*)&address,&addlen)>0)
printf("%d connected",inet_ntoa(address.sin_addr));
else
printf("not connected");
recv(new_socket,fname,255,0);
printf("file name is %s",fname);
if(fd=open(fname,O_RDONLY)<0)
{
strcpy(buffer,"Not such file found");
send(new_socket,buffer,sizeof(buffer),0);
}
else
{
while(n=read(fd,buffer,bufsize)>0)
send(new_socket,buffer,n,0);
}
close(new_socket);
}
close(create_socket);
}
client.c
int main(int argc,char *argv[])
{
int create_socket,n;
int bufsize=1024;
char *buffer=malloc(bufsize);
char fname[255];
struct sockaddr_in address;
if((create_socket=socket(AF_INET,SOCK_STREAM,0))>0)
printf("socket created\n");
address.sin_family=AF_INET;
address.sin_port=htons(15000);
inet_pton(AF_INET,argv[1],&address.sin_addr);
if(connect(create_socket,(struct sockaddr*)&address,sizeof(address))==0)
printf("%s connected\n",argv[1]);
else
printf("not connected\n");
printf("Enter the filename\n");
scanf("%s",fname);
send(create_socket,fname,strlen(fname),0);
printf("get the values");
while(n=recv(create_socket,buffer,bufsize,0)>0)
write(1,buffer,n);
return close(create_socket);
}

With the information provided, two problems with transmitting the file name are apparent:
(1) You do not check the return value of send. You cannot be sure what is sent.
(2) You choose not to send the terminating '\0' over the network. Therefore, the receiver has no way of determining when the complete file name has been received. The receiver also does not check the return value of recv. Additionally, the receiver does not bother to terminate the received filename with a '\0'.

Related

how can I read and unpack a protobuf c packed message in server side(using sockets)

I,m totally new in protobuf-c
I,m trying to create a socket connection and send protobuf packed message over the socket using c language
I packed the message within client code and send it to the server.But the server failed to receive the packed data and unpack it
my client code is
client.c
void *clientThread(void *arg)
{
Messages t_message = MESSAGES__INIT;
//while(1)
{
void *buf;
unsigned len;
int32_t s32_send_status;
t_message.name="anu";
len=messages__get_packed_size(&t_message);
buf=malloc(len);
messages__pack(&t_message,buf);
s32_send_status=send(gs32_clientSocket ,buf,len,0);
//s32_send_status=send(gs32_clientSocket ,(unsigned char *)
//(&t_message),sizeof(t_message) ,0);
if(s32_send_status>0){
printf("data send to server.\n");
}
else{
printf("failed to send data to server\n");
And my server code is
server.c
void *socketThread(void *arg)
{
Messages *t_message;
uint8_t buf[1024];
int32_t len;
// unsigned length;
//while(1)
{
gs32_valread = read( gs32_new_socket,buf,len);
if(gs32_valread==0){
printf("disconnected\n");
exit(1);
}
else if(gs32_valread<0){
printf("error\n");
exit(1);
}
else{
t_message = messages__unpack(NULL,len,buf);
printf("name=%s\n",t_message->name);
messages__free_unpacked(t_message,NULL);
}
sleep(1);
close(gs32_new_socket);
}
return NULL;
}
if my packing is correct how can I unpack it in the server side.
If anybody know this answer please help me to solve it.Thank you

to create a socket to read image from url in linux

I want to write a socket program which read an image from an url and store it at a location.
I am familiar with basic of socket programming but never created such type of socket.
Below is the code to create a socket to read data from client which i want to modify for above mentioned problem.
Please help me with this.
Thank you
Code::
include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<netdb.h>
#include<errno.h>
#include<stdlib.h>
#define sport 5000
int main(int argc,char **argv[])//Main function
{
struct sockaddr_in serveraddr;
int m,sd,acceptsd,rc,i;
char command[]="hello\n";
if((sd=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("error in socket creation\n");
exit(0);
}
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(sport);
serveraddr.sin_addr.s_addr=(INADDR_ANY);
//serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
rc=bind(sd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
if(rc<0)
{
perror("srver bind error\n");
close(sd);
exit(-1);
}
rc=listen(sd,5);
if(rc<0)
{
perror("listen error");
close(sd);
exit(-1);
}
printf("server is ready to accept connection\n");
printf("\n");
acceptsd=accept(sd,NULL,NULL);
if(acceptsd<0)
{
perror("error in accepting\n");
exit(-1);
close(sd);
}
rc=send(acceptsd,command2,sizeof(command2),0);
if(rc<0)
{
perror("error in sending\n");
close(acceptsd);
close(sd);
exit(-1);
}
close(acceptsd);
close(sd);
exit(0);
}
The code needs to use TCP sockets and implement HTTP protocol to be able to access any URLs.
Implementing HTTP protocol handling on your own is a daunting and labour intensive task. A good start would be using libcurl.

Data is getting discarded in TCP/IP with boost::asio::read_some?

I have implemented a TCP server using boost::asio. This server uses basic_stream_socket::read_some function to read data. I know that read_some does not guarantee that supplied buffer will be full before it returns.
In my project I am sending strings separated by a delimiter(if that matters). At client side I am using WinSock::send() function to send data. Now my problem is on server side I am not able to get all the strings which were sent from client side. My suspect is that read_some is receiving some data and discarding leftover data for some reason. Than again in next call its receiving another string.
Is it really possible in TCP/IP ?
I tried to use async_receive but that is eating up all my CPU, also since buffer has to be cleaned up by callback function its causing serious memory leak in my program. (I am using IoService::poll() to call handler. That handler is getting called at a very slow rate compared to calling rate of async_read()).
Again I tried to use free function read but that will not solve my purpose as it blocks for too much time with the buffer size I am supplying.
My previous implementation of the server was with WinSock API where I was able to receive all data using WinSock::recv().
Please give me some leads so that I can receive complete data using boost::asio.
here is my server side thread loop
void
TCPObject::receive()
{
if (!_asyncModeEnabled)
{
std::string recvString;
if ( !_tcpSocket->receiveData( _maxBufferSize, recvString ) )
{
LOG_ERROR("Error Occurred while receiving data on socket.");
}
else
_parseAndPopulateQueue ( recvString );
}
else
{
if ( !_tcpSocket->receiveDataAsync( _maxBufferSize ) )
{
LOG_ERROR("Error Occurred while receiving data on socket.");
}
}
}
receiveData() in TCPSocket
bool
TCPSocket::receiveData( unsigned int bufferSize, std::string& dataString )
{
boost::system::error_code error;
char *buf = new char[bufferSize + 1];
size_t len = _tcpSocket->read_some( boost::asio::buffer((void*)buf, bufferSize), error);
if(error)
{
LOG_ERROR("Error in receiving data.");
LOG_ERROR( error.message() );
_tcpSocket->close();
delete [] buf;
return false;
}
buf[len] ='\0';
dataString.insert( 0, buf );
delete [] buf;
return true;
}
receiveDataAsync in TCP Socket
bool
TCPSocket::receiveDataAsync( unsigned int bufferSize )
{
char *buf = new char[bufferSize + 1];
try
{
_tcpSocket->async_read_some( boost::asio::buffer( (void*)buf, bufferSize ),
boost::bind(&TCPSocket::_handleAsyncReceive,
this,
buf,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred) );
//! Asks io_service to execute callback
_ioService->poll();
}
catch (std::exception& e)
{
LOG_ERROR("Error Receiving Data Asynchronously");
LOG_ERROR( e.what() );
delete [] buf;
return false;
}
//we dont delete buf here as it will be deleted by callback _handleAsyncReceive
return true;
}
Asynch Receive handler
void
TCPSocket::_handleAsyncReceive(char *buf, const boost::system::error_code& ec, size_t size)
{
if(ec)
{
LOG_ERROR ("Error occurred while sending data Asynchronously.");
LOG_ERROR ( ec.message() );
}
else if ( size > 0 )
{
buf[size] = '\0';
emit _asyncDataReceivedSignal( QString::fromLocal8Bit( buf ) );
}
delete [] buf;
}
Client Side sendData function.
sendData(std::string data)
{
if(!_connected)
{
return;
}
const char *pBuffer = data.c_str();
int bytes = data.length() + 1;
int i = 0,j;
while (i < bytes)
{
j = send(_connectSocket, pBuffer+i, bytes-i, 0);
if(j == SOCKET_ERROR)
{
_connected = false;
if(!_bNetworkErrNotified)
{
_bNetworkErrNotified=true;
emit networkErrorSignal(j);
}
LOG_ERROR( "Unable to send Network Packet" );
break;
}
i += j;
}
}
Boost.Asio's TCP capabilities are pretty well used, so I would be hesitant to suspect it is the source of the problem. In most cases of data loss, the problem is the result of application code.
In this case, there is a problem in the receiver code. The sender is delimiting strings with \0. However, the receiver fails to proper handle the delimiter in cases where multiple strings are read in a single read operation, as string::insert() will cause truncation of the char* when it reaches the first delimiter.
For example, the sender writes two strings "Test string\0" and "Another test string\0". In TCPSocket::receiveData(), the receiver reads "Test string\0Another test string\0" into buf. dataString is then populated with dataString.insert(0, buf). This particular overload will copy up to the delimiter, so dataString will contain "Test string". To resolve this, consider using the string::insert() overload that takes the number of characters to insert: dataString.insert(0, buf, len).
I have not used the poll function before. What I did is create a worker thread that is dedicated to processing ASIO handlers with the run function, which blocks. The Boost documentation says that each thread that is to be made available to process async event handlers must first call the io_service:run or io_service:poll method. I'm not sure what else you are doing with the thread that calls poll.
So, I would suggest dedicating at least one worker thread for the async ASIO event handlers and use run instead of poll. If you want that worker thread to continue to process all async messages without returning and exiting, then add a work object to the io_service object. See this link for an example.

TCP Client with select , after connect waits for input

I've ran into a problem with a simple TCP Client implemented using select.
The problem is that,at the second printf it only displays before it gets to the connect() function then waits for user input. Does connect block the rest of the program until i send something? (The TCP server is also implemented using select but i didn't find anything wrong with it)
I've searched on the web and couldn't find a cause or maybe i didn't search for the right thing..
#include <includes.h>
int main()
{
int sfd;
fd_set rset;
char buff[1024]=" ";
char playerName[20]="";
int nameSet=0;
struct sockaddr_in server;
sfd= socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{ printf("socket not created\n"); return 0; }
bzero(&server,sizeof(struct sockaddr_in));
server.sin_family=AF_INET;
server.sin_port=htons(2020);
inet_aton("127.0.0.1",&server.sin_addr);
//here is the problem after %d which calls the connect() function
printf("Conexion returned:%d \n Name:",connect(sfd,(struct sockaddr *)&server,sizeof(server)));
for(;;)
{
bzero(buff,1024);
FD_ZERO(&rset);
FD_SET(0,&rset);
FD_SET(sfd,&rset);
if(select(sfd+1,&rset,NULL,NULL,NULL)<0)
{
printf("con-lost!\n");
break;
}
if(FD_ISSET(0,&rset))
{
printf("Talk: \n");
scanf("%s",buff);
if(nameSet==0)
{
strcpy(playerName,buff);
nameSet=1;
printf("Hi:%s\n",playerName);
}
if(write(sfd,buff,strlen(buff)+10)<0)
{
break;
}
}
if(FD_ISSET(sfd,&rset)>0)
{
if(read(sfd,buff,1024)<=0)
{
printf("con is off!\n");
break;
}
printf("msg rcd %s\n",buff);
}
} //endfor
close(sfd);
return 0;
} //endmain
The connect function, on a blocking socket, blocks until the connect operation succeeds or fails.
You should be warned that using select with a blocking socket, which is what your program does, does not ensure that your program will not block. When you get a select hit, that does not guarantee that a future operation will not block.
strlen(buff)+10
What's the reasoning behind the +10?

iphone tcp connection

I want to establish tcp connection between iphone and PC. On PC QTspServer is running and working (was tested with other client application).
Here is the connection method i'm using on iphone:
- (IBAction)connectToServer:(id)sender {
CFReadStreamRef read = NULL;
CFWriteStreamRef write = NULL;
NSString *host = #"192.168.1.169";
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)host, 1000, &read, &write);
CFWriteStreamOpen(write);
int k = 0;
}
The server on PC is not reacting. Any help is appropriate
By the way: Server is nothing more then a QTcpServer with replemented incomingConnection method. Here is the main function on server side:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
AbstractServer server;
server.listen(QHostAddress::Any, 1000);
QLabel label("Hello server");
label.setFixedSize(400, 400);
label.show();
return app.exec();
}
The connection is established after something was sent to the server
Check that write isn't NULL after the call to CFStreamCreatePairWithSocketToHost. If it is, the socket connection is failing.
-(IBAction)connectToServer:(id)sender {
CFWriteStreamRef write = NULL;
NSString *host = #"192.168.1.169";
int port = 1000;
CFStreamCreatePairWithSocketToHost(kCFAllocatorDefault, (CFStringRef)host, port, NULL, &write);
if (!write) {
// connection failed.
NSLog(#"Connection to %#:%d failed.",host,port);
} else {
CFWriteStreamOpen(write);
// keep a reference to the output stream for later use.
self.output = (NSOutputStream*)write;
// the function that made the output stream has "Create" in its name, so
// this method owns the write stream & should release it.
CFRelease(write);
}
}
Note that I store the output stream in a property of self. In your sample code, the stream isn't saved anywhere. You don't release it, so it still exists when the method exits, but there's no way of accessing it. If the sample -connectToServer: is representative, that error will prevent your object from sending anything to the server.