I'm trying to send a list of 600 records over TCP/IP sockets using a java server and a Blackberry client. But every time it reaches the 63th record it stops, the odd thing about this is that if I only send 200 records they are sent ok.
I haven't been able to understand why it happens, only that 63 records equals aprox to 4kB, basically it sends:
an integer with the total number of records to be sent
And for every record
an integer with the length of the string
the string
a string terminator "$$$"
Since i need to send the whole 600 i have tried to close the InputStreamReader and reopen it, also reset it but without any result.
Does anybody else have experienced this behaviour? thanks in advanced.
EDIT
Here the code that receives:
private String readfromserver() throws IOException {
int len=_in.read(); // receives the string length
if (len==0) // if len=0 then the string was empty
return "";
else {
char[] input = new char[len+1];
for (int i = 0; i < len; ++i)
input[i] = (char)_in.read();
StringBuffer s = new StringBuffer();
s.append(input);
return s.toString();
}
}
private void startRec(String data) throws IOException
{
boolean mustcontinue=true;
int len=_in.read(); // read how many records is about to receive
if (len==0) {
scr.writelog("There is no data to receive");
}
else {
for(int i=0; i<len; i++)
if (mustcontinue) {
mustcontinue=mustcontinue && showdata(readfromserver());
}
else {
scr.writelog("Inconsistency error #19");
}
}
}
the function showdata only shows the received string in a LabelField.
The code in the server:
try {
_out.write(smultiple.size()); // send the number of records
_out.flush();
for (int x=0; x<smultiple.size(); x++)
{
int l=smultiple.elementAt(x).length();
_out.write(l); // send string length
if (l>0)
_out.write(smultiple.elementAt(x)); // send string
}
_out.flush();
} catch (Exception e) {
principal.dblog(e.toString());
}
smultiple is a vector containing the strings and everyone already have the terminator $$$.
Thanks.
I think 200 goes fine and 600 -not, because the latter number is bigger than 255 :-) Your code
int len=_in.read();
probably reads a byte and not an integer (4 bytes)
Related
I want to have my Zedboard return a numeric value using the Xilinx lwIP example as a base but no matter what I do I can't figure out what stores the data received or transmitted.
I have found the void type payload but I don't know what to do with it.
Snapshot of one instance of payload and a list of lwIP files
Below is the closest function to my goal:
err_t recv_callback(void *arg, struct tcp_pcb *tpcb,
struct pbuf *p, err_t err){
/* do not read the packet if we are not in ESTABLISHED state */
if (!p) {
tcp_close(tpcb);
tcp_recv(tpcb, NULL);
return ERR_OK;
}
/* indicate that the packet has been received */
tcp_recved(tpcb, p->len);
/* echo back the payload */
/* in this case, we assume that the payload is < TCP_SND_BUF */
if (tcp_sndbuf(tpcb) > p->len) {
err = tcp_write(tpcb, p->payload, p->len, 1);
//I need to change p->paylod but IDK where it is given a value.
} else
xil_printf("no space in tcp_sndbuf\n\r");
/* free the received pbuf */
pbuf_free(p);
return ERR_OK;
}
Any guidance is appreciated.
Thanks,
Turtlemii
-I cheated and just made sure that the function has access to Global_tpcb from echo.c
-tcp_write() reads in an address and displays each char it seems.
void Print_Code()
{
/* Prepare for TRANSMISSION */
char header[] = "\rSwitch: 1 2 3 4 5 6 7 8\n\r"; //header text
char data_t[] = " \n\r\r"; //area for storing the
data
unsigned char mask = 10000000; //mask to decode switches
swc_value = XGpio_DiscreteRead(&SWCInst, 1); //Save switch values
/* Write switch values to the LEDs for visual. */
XGpio_DiscreteWrite(&LEDInst, LED_CHANNEL, swc_value);
for (int i =0; i<=7; i++) //load data_t with switch values (0/1)
{
data_t[8+2*i] = '0' + ((swc_value & mask)/mask); //convert one bit to 0/1
mask = mask >> 1;//move to next bit
}
int len_header = *(&header + 1) - header; //find the length of the
header string
int len_data = *(&data_t + 1) - data_t; //find the length of the data string
tcp_write(Global_tpcb, &header, len_header, 1); //print the header
tcp_write(Global_tpcb, &data_t, len_data, 1); //print the data
}
I have a sketch to take information (Lat, Long) from an EM-406a GPS receiver and write the information to an SD card on an Arduino shield.
The program is as follows:
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include <SD.h>
TinyGPSPlus gps;
SoftwareSerial ss(4, 3); //pins for the GPS
Sd2Card card;
SdVolume volume;
SdFile root;
SdFile file;
void setup()
{
Serial.begin(115200); //for the serial output
ss.begin(4800); //start ss at 4800 baud
Serial.println("gpsLogger by Aaron McRuer");
Serial.println("based on code by Mikal Hart");
Serial.println();
//initialize the SD card
if(!card.init(SPI_FULL_SPEED, 9))
{
Serial.println("card.init failed");
}
//initialize a FAT volume
if(!volume.init(&card)){
Serial.println("volume.init failed");
}
//open the root directory
if(!root.openRoot(&volume)){
Serial.println("openRoot failed");
}
//create new file
char name[] = "WRITE00.TXT";
for (uint8_t i = 0; i < 100; i++){
name[5] = i/10 + '0';
name[6] = i%10 + '0';
if(file.open(&root, name, O_CREAT | O_EXCL | O_WRITE)){
break;
}
}
if(!file.isOpen())
{
Serial.println("file.create");
}
file.print("Ready...\n");
}
void loop()
{
bool newData = false;
//For one second we parse GPS data and report some key values
for (unsigned long start = millis(); millis() - start < 1000;)
{
while (ss.available())
{
char c = ss.read();
//Serial.write(c); //uncomment this line if you want to see the GPS data flowing
if(gps.encode(c)) //did a new valid sentence come in?
newData = true;
}
}
if(newData)
{
file.write(gps.location.lat());
file.write("\n");
file.write(gps.location.lng());
file.write("\n");
}
file.close();
}
When I open up the file on the SD card when the program is finished executing, I get a message that it has an encoding error.
I'm currently inside (and unable to get a GPS signal, thus the 0), but the encoding problem needs to be tackled, and there should be as many lines as there are seconds that the device has been on. There's only that one. What do I need to do to make things work correctly here?
Closing the file in the loop, and never reopening it, is the reason there's only one set of data in your file.
Are you sure gps.location.lat() and gps.location.lng() return strings, not an integer or float? That would explain the binary data and the "encoding error" you see.
I am using the following code to perform a tcp socket connection and send a string to an IP. But sometimes in the response, I not receiving the entire file
Socket m_socClient;
IPSelected ="1.1.2.3"
Port = "80"
string query ="My Query"
m_socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
System.Net.IPAddress remoteIPAddress = System.Net.IPAddress.Parse(IPSelected);
System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(remoteIPAddress, Port);
m_socClient.Connect(remoteEndPoint);
try
{
if (m_socClient.Connected)
{
var reQuestToSend = "";
reQuestToSend = string.Format("POST /TMHP/Request HTTP/1.1\r\nHost:{0}\r\nContent-Length:{1}\r\n\r\n{2}", "edi-webtest.tmhp.com", Query270.Length, Query270);
byte[] bytesToSend = Encoding.ASCII.GetBytes(reQuestToSend);
byteCount = m_socClient.Send(bytesToSend, SocketFlags.None);
byte[] bytesReceived = new byte[3000];
byteCount = m_socClient.Receive(bytesReceived, SocketFlags.None);
Response271 = Encoding.ASCII.GetString(bytesReceived);
}
}
catch (Exception ex)
{
EVCommon.Log(ex.Message);
}
finally
{
m_socClient.Disconnect(false);
m_socClient.Close(5000);
}
I think the problem is with byte[] bytesReceived = new byte[3000];
Is there a way to not hardcode this number 3000. It works most of the time but for longer strings it gets only half of it.
I want it be handling variable sized messages instead of setting the byte size to 30000
Thank you
Read RFC 2616 Section 4.4. It tells you how to determine the end of the server's response so you know how many bytes to read. You have to read and process the server's response headers first in order to know how the remaining data, if any, is being transmitted. Then you can keep reading from the socket accordingly, potentially parsing what you have read, until the end of the response has actually been reached. Your current reading code is not even close to satisfying that requirement.
For example (pseudo code):
line = read a CRLF-delimited line;
responseNum = extract from line;
httpVer = extract from line;
do
{
line = read a CRLF-delimited line;
if (line == "") break;
add line to headers list;
}
while (true);
if (((responseNum / 100) != 1) &&
(responseNum != 204) &&
(responseNum != 304) &&
(request was not "HEAD"))
{
if ((headers has "Transfer-Encoding") &&
(headers["Transfer-Encoding"] != "identity"))
{
do
{
line = read a CRLF-delimited line;
chunkLen = extract from line, decode hex value;
if (chunkLen == 0) break;
read exactly chunkLen number of bytes;
read and discard a CRLF-delimited line;
}
while (true);
do
{
line = read a CRLF-delimited line;
if (line == "") break;
add line to headers list, overwrite if exists;
}
while (true);
decode/transform read data based on headers["Transfer-Encoding"] values if more than just "chunked"
}
else if (headers has "Content-Length")
{
read exactly headers["Content-Length"] number of bytes
}
else if (headers["Content-Type"] == multipart/byteranges)
{
boundary = headers["Content-Type"]["boundary"];
read and parse MIME encoded data until "--"+boundary+"--" line is reached;
}
else
{
read until disconnected;
}
}
if (((httpVer >= 1.1) && (headers["Connection"] == "close)) ||
((httpVer < 1.1) && (headers["Connection"] != "keep-alive")))
{
disconnect;
}
I leave it as an exercise for you to actually implement this in your code.
I am new in this superb place. I got help several times from this site. I have seen many answers regarding my question that was previously discussed but i am facing problem to count the number of characters using FileReader. It's working using Scanner. This is what i tried:
class CountCharacter
{
public static void main(String args[]) throws IOException
{
File f = new File("hello.txt");
int charCount=0;
String c;
//int lineCount=0;
if(!f.exists())
{
f.createNewFile();
}
BufferedReader br = new BufferedReader(new FileReader(f));
while ( (c=br.readLine()) != null) {
String s = br.readLine();
charCount = s.length()-1;
charCount++;
}
System.out.println("NO OF LINE IN THE FILE, NAMED " +f.getName()+ " IS " +charCount);
}
}`
It looks to me that each time you go through the loop, you assign the charCount to be the length of the line that iteration of the loop is concerned with. i.e. instead of
charCount = s.Length() -1;
try
charCount = charCount + s.Length();
EDIT:
If you have say the document with the contents "onlyOneLine"
Then when you first hit the while check the br.readLine() will make the BufferredReader read the first line, during the while's code block however br.readLine() is called again which advances the BufferredReader to the second line of the document, which will return null. As null is assigned to s, and you call length(), then NPE is thrown.
try this for the while block
while ( (c=br.readLine()) != null) {
charCount = charCount + c.Length(); }
I am creating a client server app using a simple socket to transfer Protocol Buffer objects between C++ and Java. I have it created on the Java side both as the client and receiver. I even got the Java to send to C++ but I am having trouble with sending from C++ to Java. Not sure how to write it. First I am sending the size and then reading the proto object.
I am using Visual Studio C++ 2008. DataGram and Bookmartlet are my proto objects.
Here is my C++ Sender Client
int loopt = 99;
do {
DataGram dataGram;
dataGram.set_state("ACK");
time ( &rawtime );
dataGram.set_status(ctime(&rawtime));
Bookmarklet* bookmarklet = dataGram.mutable_bookmarklet();
bookmarklet->set_name("TEST");
bookmarklet->set_utl("TEST");
dataGram.SerializeToArray(recvbuf,recvbuflen);
dataGram.ByteSize();
//Trouble SPOT
send(ConnectSocket,size,1,0);
send(ConnectSocket,recvbuf,recvbuflen,0);
} while (loopt > 0);
This is what I am trying to replicate from Java.
OutputStream output = socket.getOutputStream();
try {
int testtimes = 99;
while (socket.isConnected() && testtimes > 0) {
Thread.sleep(1000); // do nothing for 1000 miliseconds (1
// second)
DataGram dataGram = null;
Bookmarklet bookmarklet = Bookmarklet.newBuilder()
.setName("TEST").setUtl("TEST").build();
if (testtimes % 2 == 0) {
dataGram = DataGram.newBuilder().setState("ACK")
.setBookmarklet(bookmarklet)
.setStatus(new Date().toGMTString()).build();
} else {
dataGram = DataGram.newBuilder().setState("ACK")
.setStatus(new Date().toGMTString()).build();
}
output.write(dataGram.getSerializedSize());
output.write(dataGram.toByteArray());
testtimes--;
}
} catch (Exception e) {
e.printStackTrace();
}
Any help would be great. Thanks.
Client in Java for Reference:
InputStream input = socket.getInputStream();
int count = input.read();
int counter = 0;
while (count > 0) {
byte[] buffer = new byte[count];
count = input.read(buffer);
DataGram dataGram = DataGram.parseFrom(buffer);
Bookmarklet bookmarklet = null;
if ((bookmarklet = dataGram.getBookmarklet()) != null) {
System.out.println(bookmarklet.toString());
}
System.out.println(dataGram.getState() + " "
+ dataGram.getStatus());
count = input.read();
System.out.println(++counter);
}