i am trying to link a Unity game to a Java server using C#
when the Java server up the only way i can send data is by closing the StreamWriter (OUT.Close();) which actually closes the connection too. so i can only send data onces. or, every time i want to send a message, i have to reconnect to the server again.
when i just use Flush(), the data will not be send to the server.
Code:
NetworkStream STREAM = connection.GetStream();
StreamWriter OUT = new StreamWriter(STREAM);
OUT.Write(text);
OUT.Flush()
this is my reading code:
BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));
String inputstring = input.readLine();
You write text without a line separator with Write and read with ReadLine, so this doesn't match up. In the absence of line separators, ReadLine reads to the end of the stream, which explains why you need to close the stream. Replace Write with WriteLine.
Related
I would like to parse a PostScript file, find appropriate line number and insert a PostScript command. So, I need to read the whole file and write it as a new file along with the new commands I want to insert.
I'm using StreamReader and StreamWriter for this process.
StreamReader sr = new StreamReader("filename.ps", System.Text.Encoding.UTF8, true);
StreamWriter sw = new StreamWriter("updatedfilename.ps",true, System.Text.Encoding.UTF8);
When doing this, even though the commands are inserted in the appropriate location, some characters are getting lost due to encoding issues.
For example, please check the below image: In the After content, you can notice the yellow highlighted characters which got added during my write process.
In summary, I would like to know the process to read and write a PS file as it is without losing data because of encoding.
I am developing a networking application.
For sending and receiving data, I am using NetworkStream that I get from TcpClient.
For sending text, I wrapped NetworkStream in a StreamWriter, and I simply call StreamWriter.WriteLine(text), followed by StreamWriter.Flush().
For sending 1 byte flags from server to client (that are required for in my own communication protocol), I am using StreamWriter.BaseStream.WriteByte(byte). So, it is all the same underlying stream and it worked great until I got into this situation. The following code is where it breaks:
// This is server sending data to client.
writer.WriteLine(text);
writer.Flush();
writer.BaseStream.WriteByte(flag);
// This is client trying to read incoming data from server.
string text = reader.ReadLine(); // This will read text successfully.
int flag = reader.BaseStream.ReadByte(); // Problem is here: It will block here as if there is no data.
However, if I put some delay between flushing data and sending the byte, everything works fine...
// This is server sending data to client.
writer.WriteLine(text);
writer.Flush();
Thread.Sleep(1000); <-------------------------------- delay
writer.BaseStream.WriteByte(flag);
// This is client trying to read incoming data from server.
string text = reader.ReadLine(); // This will read text successfully.
int flag = reader.BaseStream.ReadByte(); // Now the byte is read successfully as well.
Can someone please explain why this is happening and how I can fix it?
New to TCP socket communications in C#, having a problem where I send some data across the network stream from my client app, then read it from my server app. Data comes through fine the first time, but the next time I try to send data, the old data is still in the network stream and just gets overridden up to whatever the length of the new data is. This is causing issues when trying to parse the data in the stream. I have tried adding a null termination but it doesn't seem to have any effect.
How can I empty the network stream before sending more data across?
We send a string such as this:
1|0|bob|cornell|9/14/2012 12:49:34 AM
Then another one like this:
1|0|jim|horne|9/14/2012 12:49:34 AM
But the second string goes through as :
1|0|jim|horne|9/14/2012 12:49:34 AMAM
...followed by a bunch of \0.
The last chunk is a DateTime, and it is failing to convert the string to a DateTime because of the extra AM. Even when appending \0 to the end of the string we are sending across the stream, it won't work. For example:
1|0|jim|horne|9/14/2012 12:49:34 AM\0M
It seems to treat the null termination as just another character, rather than a signal to stop reading the string.
It seems that "Flush" does nothing on NetworkStream types. Must be a dumb problem here, but any help is appreciated.
The client does this:
private static void writeToServer(MessagePacket message, NetworkStream clientStream)
{
clientStream.Write(message.ToBytes(), 0, message.ToBytes().Length);
}
The server does this:
byte[] rawMessage = new byte[4096];
while (true)
{
try
{
clientStream.Read(rawMessage, 0, 4096);
clientStream.Flush();
}
catch
{
break;
}
newPacket = new MessagePacket(rawMessage);
}
Stream.Read() returns the number of received bytes, the bytes after after that are undefined.
prefix your message with the number of bytes/chars to read ...
like: < integer>< delimeter char>< normal message>
on the receiver side, try finding the first match for the delimeter char ... parse the int in the part before that delimeter ... try reading the number of bytes/chars after the delimeter
i want to send a large data (image) approx . 1MB file though a socket connection
Question 1
following code snippet of the socket client which i currently use to send a a text message .. how i can modify this to send a file ?
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = System.Text.Encoding.ASCII.GetBytes(richTextBox1.Text+"$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
Question 2 : What modifications that required in both socket client and server to send and get large files ?
For large data portions you will probably need some kind of transmitting by portions. In your snippet you get all of the data in the array which couldn't be possible if file is large enough (or at least not suitable if it is not just one file to send).
Sending side will be something like that:
const int bufsize = 8192;
var buffer = new byte[bufsize];
NetworkStream ns = socket.GetStream();
using (var s = File.OpenRead("path"))
{
int actuallyRead;
while ((actuallyRead = s.Read(buffer, 0, bufsize)) > 0)
{
ns.Write(buffer, 0, actuallyRead);
}
}
ns.Flush();
Receiving site is just symmetric.
A socket doesn't care if you send text or binary data. Or how much you send. If there's any trouble then it is at the receiving end, code you didn't post. A classic mistake is to forget that a NetworkStream is a stream and not a sequence of packets. The Read() call at the receiving end can return any number of bytes. It won't be the number of bytes you wrote in the Write() call, depending on how routers in between the two machines broke up the IP packets and how much data is buffered in the receiver. You are probably getting away with calling Read only once because the string is short. That is definitely not going to work when you send a lot of data.
You need a protocol to help the receiver figure out when it received all the data. A simple way to do this is by first sending the length of the data. The receiver can then first read that length, then know how long to keep calling Read() to get the rest of the data.
You can arbitrarily extend this protocol by, say, sending the name of the file. Etcetera. Although that by the time you're done, you'd be close to having re-invented FTP.
If all you want to do is to send an image and you don't need any metadata, you can use code like this:
Server:
var listener = new TcpListener(address, port);
listener.Start();
using (var incoming = listener.AcceptTcpClient())
using (var networkStream = incoming.GetStream())
using (var fileStream = File.OpenWrite(imagePath))
{
networkStream.CopyTo(fileStream);
}
listener.Stop();
Client:
var client = new TcpClient();
client.Connect(address, port);
using (var networkStream = client.GetStream())
using (var fileStream = File.OpenRead(imagePath))
{
fileStream.CopyTo(networkStream);
}
client.Close();
If you want to compress the file, you can use GZipStream.
This code uses CopyTo() method, which is available in .Net 4, but you can write it yourself in earlier versions.
Can anyone please give me a tip or guide on how to create a mini program that only receive messages?
I can do a code that can receive but only if I'm sending a message (and I'm expecting a reply)
But how about the program is just waiting?
I got this code on receiving:
client.Connect("192.168.1.100",80);
Stream s = client.GetStream();
StreamReader sr = new StreamReader(s);
StreamWriter sw = new StreamWriter(s);
String r = "";
sw.AutoFlush = true;
while(true)
{
r = sr.ReadLine();
Console.WriteLine(r);
Debug.WriteLine(r);
if (sr.Peek() < 0) break;
}
This only work like I said. If I'm sending a message first, then there's a reply.
You'll want to take a look at using a TcpListener object in conjunction with the TcpClient. This link has a good example:
You can use Server Socket that is implemented in TcpListener class, but there are some problem with connecting with this when your computer is in local network.
I think that you should write 3 programms. First which sends messages to serwer, second server which would be placed in always-avaible place in internet -this one would be responsible for enqueue messages, and third one which would ask server for questions.