I am writing a program in blackberry curve 9300 using socketConnection. I get stream closed/bad socket id error when I try to read the inputstream.
Can you suggest me what could be the issue.
String url = Constants.SOCKET + serverIp + Constants.COLON + serverPort + UserInfo.getConnectionType();
//connection open
socketConne`enter code here`ction = (SocketConnection) Connector.open(url, Connector.READ_WRITE,true);
socketConnection.setSocketOption(SocketConnection.DELAY, 0);
socketConnection.setSocketOption(SocketConnection.KEEPALIVE, 1);
socketConnection.setSocketOption(SocketConnection.RCVBUF, 16834);
socketConnection.setSocketOption(SocketConnection.LINGER, 10);
outputStream = socketConnection.openDataOutputStream();
//Output stream deligated to Sender Object to send the command
sender = new Sender(outputStream);
sender.send(command);
inputStream = socketConnection.openDataInputStream();
//read inputstream
while (tobeRead < toRead && retryCount < 5) {
try {
if ((toRead - tobeRead) > 8192) {
readBufferLength = 8192;
} else {
readBufferLength = (toRead - tobeRead);
}
buffer = new byte[readBufferLength + 1];
bytesRead = inputStream.read(buffer, 0, readBufferLength);
sb.append(new String(buffer, 0, bytesRead));
tobeRead += bytesRead;
totalBytesRead += bytesRead;
} catch (Exception cce) {
}
}
say if number of bytes to read is 5192. I get say 2123 bytes then it iterates the loop, next time while reading it fails. I run this in seperate thread. I use WIFI network for connectivity
Related
I'm newbee in socket program.
I made my server program with good sample program using select function.
It works well about 20,000 connections over.
But, in some case, connection accept twice consequence without
receive data from first socket.
Only data received from second socket connection.
After that, first socket resource cannot release.
FD_SET and FD_ISSET are not working with first socket in case of consequence accept I think.
Working clients are 6.
Before this situation,
accept, receive data, and close socket, accept, rcv
data, close, ...
In case, accept,
accept, receive data from second socket, and close second socket.
Lost first socket connection.
After that, accept function assign second socket descriptor.
What is problem?
How can release fisrt socket?
BR
Paul
My code is as follow:
while(1)
{
//clear the socket set
FD_ZERO (&readfds);
//add master socket to set
FD_SET (sever_socket, &readfds);
max_sd = sever_socket;
//add child sockets to set
for ( i = 0 ; i < MAX_CLIENT ; i ++)
{
//socket descriptor
sd = client_socket [i];
//if valid socket descriptor then add to read list
if (sd > 0)
{
FD_SET( sd , &readfds);
}
//highest file descriptor number, need it for the select function
if(sd > max_sd)
{
max_sd = sd;
}
}
//wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely
activity = select ( max_sd + 1 , &readfds , NULL , NULL , NULL);
if ((activity < 0) && (errno!=EINTR))
{
LOG_F (WARNING, "select error");
}
//If something happened on the master socket, then its an incoming connection
if (FD_ISSET(sever_socket, &readfds))
{
if ((new_socket = accept (sever_socket, (struct sockaddr *) &address, (socklen_t*) &addrlen)) < 0)
{
perror("accept");
exit(EXIT_FAILURE);
}
//inform user of socket number - used in send and receive commands
LOG_F (INFO, "New connection, socket fd is %d, ip is : %s, port : %d",
new_socket, inet_ntoa(address.sin_addr), ntohs(address.sin_port));
//add new socket to array of sockets
for (i = 0; i < MAX_CLIENT; i++)
{
//if position is empty
if( client_socket[i] == 0 )
{
client_socket[i] = new_socket;
LOG_F (INFO, "Adding to list of sockets as %d" , i);
break;
}
}
}
for (i = 0; i < MAX_CLIENT; i++)
{
sd = client_socket[i];
if (FD_ISSET (sd , &readfds))
{
memset (&rcvBuf, 0x00, sizeof(rcvBuf));
if ((fp = fdopen (sd, "r")) == NULL)
{
LOG_F (WARNING, "TCP_SOCKET FD_OPEN Error");
close (sd);
client_socket[i] = 0;
}
else
{
ret = ioctl (sd, FIONREAD, &nread);
if (nread == 0)
{
fclose (fp);
close (sd);
client_socket[i] = 0;
LOG_F (WARNING, "Client disconnected(as %d, fd %d)", i, sd);
}
else
{
len = recv (sd, rcvBuf, nread, 0);
if (len > 0)
{
LOG_F (INFO, "RECV size %d" , len);
...
do_msg_handler ()
}
}
...
I am developing client-server application which transfers data via UDP.
I am facing the problem of dropped packets. I added socket buffer checking to detect potential overflow. Also my app checks sequence of received numbers in packets. Packets have fixed size. If free space of socket buffer is less than threshold (size of 3 packets for example) then "Critical level of buffer" message is logged. If number of packet is skipped in sequence then corresponding message is logged. There is code:
UdpServer::UdpServer(asio::io_service& io, uint16_t port, uint32_t packetSize) : CommunicationBase(io, port),
m_socket(io, asio::ip::udp::endpoint(asio::ip::address_v6::any(), m_port))
{
m_buffer = new uint8_t[packetSize];
m_packetSize = packetSize;
m_socketBufferSize = m_packetSize * 32;
m_criticalLevel = 5 * m_packetSize;
asio::ip::udp::socket::receive_buffer_size recieveBuffSize(m_socketBufferSize);
m_socket.set_option(recieveBuffSize);
}
UdpServer::~UdpServer()
{
std::free(m_buffer);
}
void UdpServer::StartReceive(std::function<void(uint8_t* buffer, uint32_t bytesCount)> receiveHandler)
{
m_onReceive = receiveHandler;
Receive();
}
inline void UdpServer::Receive()
{
m_socket.async_receive(asio::null_buffers(), [=](const boost::system::error_code& error, size_t bytesCount)
{
OnReceive(bytesCount, error);
});
}
void UdpServer::OnReceive(size_t bytesCount, const boost::system::error_code& error)
{
static uint16_t lastSendNum = 65535;
uint16_t currentNum = 0;
uint16_t diff = 0;
if (error)
{
if (error == asio::error::operation_aborted)
{
logtrace << "UDP socket reports operation aborted, terminating";
return;
}
logerror << "UDP socket error (ignoring): " << error.message();
}
else
{
asio::ip::udp::endpoint from;
boost::system::error_code receiveError;
size_t bytesRead = 0;
size_t bytesAvailable = m_socket.available();
while (bytesAvailable > 0)
{
if (m_socketBufferSize - bytesAvailable < m_criticalLevel)
{
logwarning << "Critical buffer level!";
}
bytesRead = m_socket.receive(asio::buffer(m_buffer, m_packetSize), 0, receiveError);
if (receiveError)
{
logerror << "UDP socket error: " << receiveError.message();
break;
}
currentNum = *reinterpret_cast<uint16_t*>(m_buffer);
diff = currentNum - lastSendNum;
if (diff != 1)
{
logdebug << "Chunk skipped: " << diff << ". Last " << lastSendNum << " next " << currentNum;
}
lastSendNum = currentNum;
if (m_onReceive)
{
m_onReceive(m_buffer, bytesRead);
}
bytesAvailable = m_socket.available();
}
}
Receive();
}
Even if checking of buffer status and packet processing m_onReceive are disabled and bytesAvailable > 0 replaced with true, udp packets are dropped. Speed rate is ~71 Mb/s via 1Gb Ethernet.
Windows 10 is used. Also I checked netstat -s result: no reassembly failures. Socket buffer is never being overflowed.
I want to send several files from Server to the Client but I'm having a problem.
Server sendfile code:
while ((len = fread(Buffer,1,sizeof(Buffer), fs)) > 0)
{
if((resultEnviar = send(ClientSocket,Buffer,len,0)) < 0){
printf("ERROR: Failed to send file %s.\n", nombreArchivoADescargar.c_str());
break;
}
sumEnviada+=resultEnviar;
}
fclose(fs);
Client receiveFile code:
//shutdown(sock, SD_SEND); ???????
do{
recvVal = recv(sock, Buffer2, sizeof(Buffer2), 0);
if (recvVal <= 0){
printf("Can't read from socket");
recvVal =0;
fclose(fp);
continue;
}else{
int off =0;
do{
int write_sz = fwrite(Buffer2, 1, recvVal, fp);
if (write_sz < 0){
printf("Can't write to file");
fclose(fp);
break;};
if (write_sz == 0) {cout<<endl<<"Nada que copiar"<<endl; break;}
off += write_sz;
}while(off<recvVal);
bzero(Buffer2, 1024);
contador+=off;
}
}while (contador<LongitudArchivo);
cout<<endl<<"Numero de bytes recibidos: "<<contador<<endl<<endl;
printf("Ok received from client!\n");
fclose(fp);
If I don't use the SHUTDOWN(sock, SD_SEND) I don't receive all the expected bytes but if I use it I don't know how to send more files (how to wake up the send part of the socket).
Thanks!
I don't see what shutdown() has to do with it. You should receive all the bytes either way. If you want to send multiple files, you will have to send the length ahead of each one and read exactly that many following bytes from the socket into each target file.
NB If recv() returns zero you should close the socket and break. If it returns -1 you should log the errno, e.g. via perror(), close the socket, and break.
I am trying to download a pdf file on my mobile (using Java ME) using SocketConnection Api. The idea is to send the server a HTTP GET request, and it replies back with the data for pdf file. However, the problem I am facing is that the server initially replies back with string data (the HTTP Headers), and then the binary data. I just want to store the binary data (the pdf file).
I have written this code so far, and it works perfectly fine as far as the server replies back with string data. However, when it replies back with binary data, this code still tries to store everything as string, correctly storing the initially returned HTTP Headers (not required) and then garbled bits corresponding to the binary data of my PDF file.
public void FileDownload() {
try {
sc = (SocketConnection) Connector.open("socket://" + hostname + ":" + port);
OutputStream os = sc.openOutputStream();
os.write(("GET " + link_to_file_to_be_downloaded + " HTTP/1.0\r\n").getBytes("UTF-8"));
os.write(("HOST: " + hostname + "\r\n").getBytes("UTF-8"));
os.write(("\r\n").getBytes("UTF-8"));
os.flush();
os.close();
String url = "file:///E:/Data/" + "binary_data.pdf";
FileConnection fconn = (FileConnection) Connector.open(url, Connector.READ_WRITE);
if (!fconn.exists()) {
fconn.create();
}
OutputStream ops = fconn.openOutputStream();
byte data = 0;
in = sc.openInputStream();
data = (byte) in.read();
while (data != -1) {
ops.write(data);
data = (byte) in.read();
}
ops.flush();
ops.close();
fconn.close();
} catch (IOException ex) {
parent_class.main_form.append("Exception occured while "
+ "downloading file: " + ex.toString() + "\n");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
parent_class.main_form.append("Exception occured while "
+ "downloading file: " + ex.toString() + "\n");
}
}
}
}
This is what gets stored in the file "binary_data.pdf" using this code -
HTTP/1.1 200 OK
Date: Sun, 25 Mar 2012 07:03:10 GMT
Server: Apache/2.2.14 (Ubuntu)
Last-Modified: Tue, 20 Mar 2012 22:00:45 GMT
ETag: "420050-12bad-4bbb3ce85fd21"
Accept-Ranges: bytes
Content-Length: 76717
Content-Type: application/pdf
Via: 1.0 www.XXX.XXX.org
Connection: close
%PDF-1.4
%????
3 0 obj <<
/Length 4077
/Filter /FlateDecode
>>
stream
x??ZYs?6~????9U.?#??Udg?M*qYJ???T-4?fq? #Z????<FT?}
lt7??n???_???4?s???????"
3????<???^?V?z??M?z??m?^????V???o??S'm6?????.??/Sx??Y?av?MB?*b^?f??/?IO??B??q??/?(??aT?a?##??,?%???Z8? ?]??-?\?]??????nw?2?;?????Z?;?[}??????&J=ml??-??V?|??:??"?(?Gf??D??~?QW?U?Z???cP?b???QX
(This operation might be simpler using the high level HttpConnection api, but I wish to understand how everything works at the most basic level, and hence I am using the SocketConnection api instead.)
In short, what I wish my app to do is simply interpret the data replied by the server correctly, either as string or binary, and then accordingly store the binary file (possibly discarding the string HTTP headers).
I found the solution. Below is the working code.
I am first storing the header response as a string. Headers are terminated by \r\n\r\n, (so, read in bytes upto these characters). Later am storing the (possibly) binary data in a file separately.
public String FileDownloadNonPersistently() {
String server_reply = new String();
try {
sc = (SocketConnection) Connector.open("socket://" + hostname + ":" + port);
os = sc.openOutputStream();
os.write(("GET " + link_to_file_to_be_downloaded +
" HTTP/1.0\r\n").getBytes("UTF-8"));
os.write(("HOST: " + hostname + "\r\n").getBytes("UTF-8"));
os.write(("\r\n").getBytes("UTF-8"));
os.flush();
os.close();
in = sc.openInputStream();
// 1. Read the response header from server separately beforehand.
byte data;
String temp_char = "";
while (!"\r\n\r\n".equals(temp_char)) {
data = (byte) in.read();
server_reply += String.valueOf((char) data);
if (((char) data) == '\r' || ((char) data) == '\n') {
temp_char += String.valueOf((char) data);
} else {
temp_char = "";
}
}
// 2. Recieving the actual data, be it text or binary
current = 0;
mybytearray = new byte[filesize];
bytesRead = in.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead = in.read(mybytearray, current,
(mybytearray.length-current));
if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);
// Store recieved data to file, if set true from options
if (tcp_save_downloaded_file == true) {
// decide an appropriate file name acc. to download link
String url = "file:///E:/Data/" + "tcp_downloaded_file.pdf";
FileConnection fconn = (FileConnection)
Connector.open(url, Connector.READ_WRITE);
if (!fconn.exists()) { // XXX. what if file already present? overwrite or append mode?
fconn.create();
}
OutputStream ops = fconn.openOutputStream();
ops.write(mybytearray, 0 , current);
ops.flush();
ops.close();
}
} catch (Exception ex) {
parent_class.main_form.append("Exception occured while "
+ "downloading file: " + ex.toString() + "\n\n");
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ex) {
parent_class.main_form.append("Exception occured while "
+ "closing inputstream "
+ "after downloading file: " + ex.toString() + "\n\n");
}
}
// XXX. see if you need to close the OutputStreams and
// SocketConnection as well.
return server_reply;
}
}
The first 10 lines are the HTTP message headers. For more information on them please go to https://www.rfc-editor.org/rfc/rfc2616#page-31.
The blank line identifies where the body starts.
You can start saving the pdf content from line 12 onwards, but you should do it using a different read method.
Instead of
data = (byte) in.read();
while (data != -1) {
ops.write(data);
data = (byte) in.read();
}
please try
byte buff[] = new byte[1024];
int len = in.read(buff);
while (len > 0) {
ops.write(buff, 0, len);
len = in.read(buff);
}
i am trying here to send the content of a text file by the server and send it to the client
this is the server
Socket server = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 9050);
server.Bind(localEP);
server.Listen(10);
Console.WriteLine("Waiting for Client...");
Socket client = server.Accept();
IPAddress clientAddress = ((IPEndPoint)client.RemoteEndPoint).Address;
Console.WriteLine("Got connection from " + clientAddress);
NetworkStream stream = new NetworkStream(client);
StreamReader reader = new StreamReader(stream);
StreamWriter writer = new StreamWriter(stream);
writer.WriteLine("Welcome to my test server");
writer.Flush();
string line = null;
while ((line = reader.ReadLine()).Length != 0)
{
Console.WriteLine("loooking for this file:" + line);
System.IO.FileInfo fi = new System.IO.FileInfo(line);
Console.WriteLine("Found");
writer.WriteLine("File Size: " + fi.Length + "\nContent:");
StreamReader tr = new StreamReader(line);
string s = null;
//string b = "";
while((s= tr.ReadLine()).Length != 0)
{
writer.WriteLine(tr.ReadLine());
writer.Flush();
}
tr.Close();
}
client.Close(); server.Close();
the part of the client where it reads from the server is this
String line = null;
line = textBox3.Text;
writer.WriteLine(line); // Send line to Server
writer.Flush();
string s = null;
// Read line from server, then echo on the screen
while((s= reader.ReadLine()).Length != 0)
{
textBox4.Text += reader.ReadLine() + "\r\n\r\n";
}
when i run the code, no errors at all, but the client get stuck, and when i stop the server, the content of the file will show,,, BTW, its a GUI application
while ((s = reader.ReadLine()) != null) {
textBox4.Text += s;
}
Sample code for StreamReader uses the construct below to detect end of stream. Also - do you really want to read two lines in that loop?
while (reader.Peek() >= 0)
{
s= reader.ReadLine();
textBox4.Text += s + Environment.NewLine + Environment.NewLine;
}
You mentioned that this is a GUI app? If so, on which thread are you doing the reading? If you are doing the read on the main thread, then the application messageloop will be frozen and nothing will show up until you stop the other side and kill the connection.