i have a bare bones chat client in console. Here's the code
For server
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace chat_server
{
class Program
{
static TcpListener server = new TcpListener(IPAddress.Any, 9999);
static void input(object obs)
{
StreamWriter writer = obs as StreamWriter;
string op = "nothing";
while (!op.Equals("exit"))
{
Console.ResetColor();
Console.WriteLine("This is the " + Thread.CurrentThread.ManagedThreadId);
Console.WriteLine("Enter your text(type exit to quit)");
op = Console.ReadLine();
writer.WriteLine(op);
writer.Flush();
}
}
static void output(Object obs)
{
StreamReader reader = obs as StreamReader;
Console.ForegroundColor = ConsoleColor.Green;
while (true)
{
Console.WriteLine(reader.ReadLine());
}
}
static void monitor()
{
while (true)
{
TcpClient cls = server.AcceptTcpClient();
Thread th = new Thread(new ParameterizedThreadStart(mul_stream));
th.Start(cls);
}
}
static void mul_stream(Object ob)
{
TcpClient client = ob as TcpClient;
Stream streams = client.GetStream();
StreamReader reads = new StreamReader(streams);
StreamWriter writs = new StreamWriter(streams);
new Thread(new ParameterizedThreadStart(output)).Start(reads);
input(writs);
}
static void Main(string[] args)
{
server.Start();
monitor();
server.Stop();
Console.ReadKey();
}
}
}
and here's the client code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace chat_client
{
class Program
{
static StreamReader reader;
static StreamWriter writer;
static Thread input_thread;
static void input()
{
string op = "nothing";
while (!op.Equals("exit"))
{
Console.ResetColor();
Console.WriteLine("Enter your text(type exit to quit)");
op = Console.ReadLine();
writer.WriteLine(op);
writer.Flush();
}
}
static void output()
{
Console.ForegroundColor = ConsoleColor.Blue;
while (true)
{
Console.WriteLine(reader.ReadLine());
}
}
static void Main(string[] args)
{
Console.WriteLine("Enter the ip address");
string ip = Console.ReadLine();
TcpClient client = new TcpClient(ip,9999);
NetworkStream stream = client.GetStream();
reader = new StreamReader(stream);
writer = new StreamWriter(stream);
input_thread = new Thread(input);
input_thread.Start();
/*
writer.Write("Hello world");
writer.Flush();
Console.WriteLine("Message Sent");*/
output();
client.Close();
Console.ReadKey();
}
}
}
Now the thing is that i am having some issues converting this code to GUI. For instance the input function in the server which delivers the message through a specific stream to a client should be somewhat equivalent to SEND button in GUI.
However each thread creates its own stream and i don't think that creating seprate event handlers on different threads would be a good idea.
In short i need some advice on where to start with this project.
Thank you.
Networking is hard. Your current approach, which is just reading everything and treating everything as complete messages, is fragile. It works during debugging but will fail during production since TCP is stream based.
Instead, you could use an existing framework to abstract away the networking layer. As it happens, I've made a framework which is open source (LGPL).
In this case we'll just want to be able to chat. So I added a chat message definition like this:
public class ChatMessage
{
public DateTime CreatedAt { get; set; }
public string UserName { get; set; }
public string Message { get; set; }
}
That message is put in a shared assembly (used both by the client and the server).
The server itself is defined like this:
public class ChatServer : IServiceFactory
{
private readonly List<ClientChatConnection> _connectedClients = new List<ClientChatConnection>();
private readonly MessagingServer _server;
public ChatServer()
{
var messageFactory = new BasicMessageFactory();
var configuration = new MessagingServerConfiguration(messageFactory);
_server = new MessagingServer(this, configuration);
}
public IServerService CreateClient(EndPoint remoteEndPoint)
{
var client = new ClientChatConnection(this);
client.Disconnected += OnClientDisconnect;
lock (_connectedClients)
_connectedClients.Add(client);
return client;
}
private void OnClientDisconnect(object sender, EventArgs e)
{
var me = (ClientChatConnection) sender;
me.Disconnected -= OnClientDisconnect;
lock (_connectedClients)
_connectedClients.Remove(me);
}
public void SendToAllButMe(ClientChatConnection me, ChatMessage message)
{
lock (_connectedClients)
{
foreach (var client in _connectedClients)
{
if (client == me)
continue;
client.Send(message);
}
}
}
public void SendToAll(ChatMessage message)
{
lock (_connectedClients)
{
foreach (var client in _connectedClients)
{
client.Send(message);
}
}
}
public void Start()
{
_server.Start(new IPEndPoint(IPAddress.Any, 7652));
}
}
See? No networking code anywhere.
The client is event easier:
static class Program
{
private static MainForm _mainForm;
private static MessagingClient _client;
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
ConfigureChat();
_mainForm = new MainForm();
Application.Run(_mainForm);
}
private static void ConfigureChat()
{
_client = new MessagingClient(new BasicMessageFactory());
_client.Connect(new IPEndPoint(IPAddress.Loopback, 7652));
_client.Received += OnChatMessage;
}
private static void OnChatMessage(object sender, ReceivedMessageEventArgs e)
{
_mainForm.InvokeIfRequired(() => _mainForm.AddChatMessage((ChatMessage)e.Message));
}
public static void SendChatMessage(ChatMessage msg)
{
if (msg == null) throw new ArgumentNullException("msg");
_client.Send(msg);
}
}
The full example is available here: https://github.com/jgauffin/Samples/tree/master/Griffin.Networking/ChatServerClient
Update:
Since it's a school project and you can't use anything other than .NET I would probably use the easiest possible approach. And that's to use new line ("\r\n") as delimiter.
so in each side you just used var chatMessage = streamReader.ReadLine() and streamWriter.WriteLine("Chat message");
Related
The TcpListener server does not start, I want to take readings from a humidity sensor connected to ESP8266, which should connect to it, an error related to null comes out. The server is being raised on the Xamarin application.
I have already tried to register server initialization in different parts of the code, but still nothing comes out. Tell me what the error is.
using System;
using Xamarin.Forms;
using System.Net.Sockets;
using System.Net;
using Android.Widget;
using System.Text;
using System.Collections.Generic;
namespace Teplica
{
public partial class MainPage : ContentPage
{
private string ip = "192.168.1.2";
private int port = 8545;
private bool door = true;
TcpListener server;
TcpClient client = null;
NetworkStream stream = null;
private bool Timer = true;
private byte[] data = null;
StringBuilder builder = null;
private List<string> list = new List<string>();
public MainPage()
{
InitializeComponent();
server = new TcpListener(IPAddress.Parse(ip), 8545);
server.Start();//NullReferencesException
client = server.AcceptTcpClient();
stream = client.GetStream();
Device.StartTimer(TimeSpan.FromSeconds(1), TeplicaTimer);
}
private bool TeplicaTimer()
{
data = new byte[256];
builder = new StringBuilder();
int bytes = stream.Read(data,0, data.Length);
builder.Append(Encoding.UTF8.GetString(data, 0, bytes));
list.Add(Convert.ToString(builder));
DataVlazhnost.ItemsSource = list;
return Timer;
}
private void OpenDoor_Clicked(object sender, EventArgs e)
{
if (door)
{
Toast.MakeText(Android.App.Application.Context, "Открытие двери", ToastLength.Short).Show();
OpenDoor.Text = "Закрыть";
door = false;
}
else
{
Toast.MakeText(Android.App.Application.Context, "Закрытие двери", ToastLength.Short).Show();
OpenDoor.Text = "Открыть";
door = true;
}
}
private void Water_Clicked(object sender, EventArgs e)
{
Toast.MakeText(Android.App.Application.Context, "Подача воды", ToastLength.Short).Show();
}
}
}
I have a class (installed as a Window Service) that listens to HTTP Requests.
using System;
using System.ServiceProcess;
using System.IO;
using System.Net;
using System.Net.Sockets;
class Program : System.ServiceProcess.ServiceBase
{
public static String navn = "PM_RequestHandler";
private bool RunThread = true;
public void StartMe()
{
IPAddress localAddr = System.Net.IPAddress.Parse("127.0.0.1");
System.Net.Sockets.TcpListener server = new System.Net.Sockets.TcpListener(localAddr, 1234); // http://localhost:1234
server.Start();
Byte[] bytes = new Byte[1024];
String data = null;
while (RunThread)
{
TcpClient client = server.AcceptTcpClient();
data = null;
NetworkStream stream = client.GetStream();
stream.Read(bytes, 0, bytes.Length);
data = System.Text.Encoding.ASCII.GetString(bytes);
// LOG
StreamWriter sw = new StreamWriter("c:\\PM_RequestHandler.txt", true);
sw.WriteLine(data);
sw.Close();
client.Close();
}
}
protected override void OnStart(string[] args)
{
System.Threading.Thread thr = new System.Threading.Thread(new
System.Threading.ThreadStart(this.StartMe));
thr.Start();
base.OnStart(args);
}
protected override void OnStop()
{
RunThread = false;
base.OnStop();
}
static void Main(string[] args)
{
System.ServiceProcess.ServiceBase.Run(new Program());
}
}
I have a web service I run (locally) to try my previous class.
I use SoapUI to invoke it.
The problem is that the web service uses POST requests and I cannot catch them.
My log is empty and it seems that the class just catches Get requests made manually in the browser.
Why is that so?
I am very new to sockets with C# and I have been working on trying to get a socket to work with localhost. Here is the main UDP code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class NetUDP
{
private UdpClient udp;
private IPEndPoint endPont;
public NetUDP(int port_local, int port_global, string ip_global, string ip_local)
{
Console.WriteLine(IPAddress.Any.ToString());
udp = new UdpClient(IPAddress.Any.ToString(), port_global);
endPont = new IPEndPoint(IPAddress.Parse(ip_global), port_global);
udp.Connect(ip_global, port_global);
}
public NetUDP()
{
}
public void UDPinit(int port_local, int port_global, string ip_global, string ip_local)
{
Console.WriteLine();
udp = new UdpClient("127.0.0.1", port_global);
endPont = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port_global);
udp.Connect("127.0.0.1", port_global);
}
public void sendDataUDP(string info)
{
Byte[] SendByte = Encoding.ASCII.GetBytes(info);
udp.Send(SendByte, SendByte.Length);
}
public string getDataUDP()
{
Byte[] get = udp.Receive(ref endPont);
return Encoding.ASCII.GetString(get);
}
public void closeUDP()
{
udp.Close();
}
}
}
The problem is every time I do this code when I try to retrieve info from another UDP C# program (on the same machine) it freezes. I know it keeps on looking for info coming it's way, but id there a way to put a timeout on the receive command or do I have to make an event handler to prevent this freezing? The ports connect just fine and do not show any form of error or exception. Thank you for your help in advance!
class Program
{
static void Main(string[] args)
{
var serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8500);
NetUDP udp = new NetUDP(serverEndPoint);
UdpClient localClient = new UdpClient();
Task.Delay(20000);
var dgram = Encoding.ASCII.GetBytes("Hello Server");
localClient.Send(dgram, dgram.Length, serverEndPoint); // Send "Hello Server" to Server
Console.Read();
}
}
class NetUDP
{
private UdpClient udp;
private IPEndPoint endPont;
public NetUDP() { }
public NetUDP(IPEndPoint serverEndPoint)
{
udp = new UdpClient(serverEndPoint); // Bind the EndPoint
// Receive any IPAddress send to the 8555 port
IPEndPoint receiveEndPoint = new IPEndPoint(IPAddress.Any, 8555);
Task.Run(() =>
{
try
{
while (true)
{
// This Receive will block until receive an UdpClient
// So, run in another thread in thread pool
var bytes = udp.Receive(ref receiveEndPoint);
Console.WriteLine(Encoding.ASCII.GetString(bytes));
}
}
catch (Exception ex)
{
// TODO
}
finally
{
udp.Close();
}
});
}
}
Here is and UdpChat demo in github: UdpChat
I need to implement a TCP client application. The client and the server send messages to each other. I want to make this program scalable enough to handle connections to multiple servers at the same time. It seems like asynchronous sockets is the way to go for this. I'm new to C# so I'm pretty sure I don't know what I'm doing here. I wrote some classes and a simple console program to get started with. Eventually, I want to create a Windows Forms application but I want to start small and simple first. The Client class runs in its own thread. Is this all thread-safe and correctly done? It's a lot of code and I tried to cut out some fat.
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace FastEyeClient
{
class Program
{
static void Main(string[] args)
{
Client client = new Client();
client.ConnectEvent += new ConnectEventHandler(OnConnect);
client.SetLiveStatusEvent += new SetLiveStatusEventHandler(OnSetLiveStatus);
client.Connect("hostname", 1987);
Thread.Sleep(1000);
client.SetLiveStatus("hostname", true);
}
private static void OnConnect(object sender, ConnectEventArgs e)
{
Console.WriteLine(e.Message);
}
private static void OnSetLiveStatus(object sender, SetLiveStatusEventArgs e)
{
Console.WriteLine(e.Message);
}
}
}
Client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace FastEyeClient
{
public delegate void ConnectEventHandler(object sender, ConnectEventArgs e);
public delegate void SetLiveStatusEventHandler(object sender, SetLiveStatusEventArgs e);
public class Client : IDisposable
{
public event ConnectEventHandler ConnectEvent;
public event SetLiveStatusEventHandler SetLiveStatusEvent;
ServerManager m_Manager;
EventWaitHandle m_WaitHandle;
readonly object m_Locker;
Queue<Event> m_Tasks;
Thread m_Thread;
public Client()
{
m_Manager = new ServerManager(this);
m_WaitHandle = new AutoResetEvent(false);
m_Locker = new object();
m_Tasks = new Queue<Event>();
m_Thread = new Thread(Run);
m_Thread.Start();
}
public void EnqueueTask(Event task)
{
lock (m_Locker)
{
m_Tasks.Enqueue(task);
}
m_WaitHandle.Set();
}
public void Dispose()
{
EnqueueTask(null);
m_Thread.Join();
m_WaitHandle.Close();
}
private void Run()
{
while (true)
{
Event task = null;
lock (m_Locker)
{
if (m_Tasks.Count > 0)
{
task = m_Tasks.Dequeue();
if (task == null)
{
return;
}
}
}
if (task != null)
{
task.DoTask(m_Manager);
}
else
{
m_WaitHandle.WaitOne();
}
}
}
public void Connect(string hostname, int port)
{
EnqueueTask(new ConnectEvent(hostname, port));
}
public void SetLiveStatus(string hostname, bool status)
{
EnqueueTask(new SetLiveEvent(hostname, status));
}
public void OnConnect(bool isConnected, string message)
{
if (ConnectEvent != null)
{
ConnectEvent(this, new ConnectEventArgs(isConnected, message));
}
}
public void OnSetLiveStatus(string hostname, string message)
{
if (SetLiveStatusEvent != null)
{
SetLiveStatusEvent(this, new SetLiveStatusEventArgs(hostname, message));
}
}
}
}
Server.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace FastEyeClient
{
public class Server
{
private ServerManager m_Manager;
private string m_Hostname;
private bool m_IsLive;
private class StateObject
{
public Socket AsyncSocket = null;
public const int BufferSize = 1024;
public byte[] Buffer = new byte[BufferSize];
public StringBuilder Builder = new StringBuilder();
}
public Server(ServerManager manager, Socket socket)
{
try
{
m_Manager = manager;
IPEndPoint endPoint = (IPEndPoint)socket.RemoteEndPoint;
IPAddress ipAddress = endPoint.Address;
IPHostEntry hostEntry = Dns.GetHostEntry(ipAddress);
Hostname = hostEntry.HostName;
IsLive = false;
StateObject state = new StateObject();
state.AsyncSocket = socket;
socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception)
{
}
}
public string Hostname
{
get
{
return m_Hostname;
}
set
{
m_Hostname = value;
}
}
public bool IsLive
{
get
{
return m_IsLive;
}
set
{
m_IsLive = value;
}
}
private void ReceiveCallback(IAsyncResult result)
{
try
{
StateObject state = (StateObject)result.AsyncState;
Socket socket = state.AsyncSocket;
int read = socket.EndReceive(result);
if (read > 0)
{
state.Builder.Append(Encoding.ASCII.GetString(state.Buffer, 0, read));
if (state.Builder.Length > 1)
{
string messages = state.Builder.ToString();
ParseMessages(messages);
}
}
StateObject newState = new StateObject();
newState.AsyncSocket = socket;
socket.BeginReceive(newState.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), newState);
}
catch (Exception)
{
}
}
private void ParseMessages(string messages)
{
string[] messagesArray = messages.Split('\n');
foreach (string message in messagesArray)
{
string[] tokens = message.Split(',');
if (tokens[0].Contains("#"))
{
ParseServerMessage(tokens);
}
}
}
private void ParseServerMessage(string[] tokens)
{
tokens[0].Remove(0, 1);
if (tokens[0] == "4")
{
bool status;
if (tokens[1] == "0")
{
status = false;
m_Manager.SetLiveStatus(m_Hostname, status);
}
else if (tokens[1] == "1")
{
status = true;
m_Manager.SetLiveStatus(m_Hostname, status);
}
}
}
}
}
ServerManager.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
namespace FastEyeClient
{
public class ServerManager
{
private Client m_Client;
private Dictionary<string, Server> m_Servers;
private object m_Locker;
public ServerManager(Client client)
{
m_Client = client;
m_Servers = new Dictionary<string, Server>();
m_Locker = new object();
}
public void AddServer(string hostname, int port)
{
try
{
IPAddress[] IPs = Dns.GetHostAddresses(hostname);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.BeginConnect(IPs, port, new AsyncCallback(ConnectCallback), socket);
}
catch (Exception)
{
bool isConnected = false;
string message = "Could not connect to server.";
m_Client.OnConnect(isConnected, message);
}
}
private void ConnectCallback(IAsyncResult ar)
{
bool isConnected;
string message;
try
{
Socket socket = (Socket)ar.AsyncState;
socket.EndConnect(ar);
IPEndPoint endPoint = (IPEndPoint)socket.RemoteEndPoint;
IPAddress ipAddress = endPoint.Address;
IPHostEntry hostEntry = Dns.GetHostEntry(ipAddress);
string hostname = hostEntry.HostName;
lock (m_Servers)
{
if (m_Servers.ContainsKey(hostname))
{
isConnected = false;
message = "Client is already connected to server";
}
else
{
m_Servers.Add(hostname, new Server(this, socket));
isConnected = true;
message = "Successfully connected.";
}
}
m_Client.OnConnect(isConnected, message);
}
catch (Exception)
{
isConnected = false;
message = "Could not connect to server.";
m_Client.OnConnect(isConnected, message);
}
}
public void SetLiveStatus(string hostname, bool newStatus)
{
string message;
lock (m_Locker)
{
if (m_Servers.ContainsKey(hostname))
{
if (m_Servers[hostname].IsLive == newStatus)
{
message = "Server is already set to this status.";
}
else
{
m_Servers[hostname].IsLive = newStatus;
message = "Successfully set new status.";
}
}
else
{
message = "Server not found.";
}
}
m_Client.OnSetLiveStatus(hostname, message);
}
}
}
Does it Run?
Does it throw an exception(s)?
Pitfall in trying to run server code in multiple threads:
AVOID attempting to manipulate, read or write a socket in different threads. Have one thread accept connections from the server socket and spawn a thread to handle transactions. If you get too many threads going on at once, you're going to have have 1 thread handle several sockets.
No it is not thread safe.
A subscriber can have unsubscribe before between the check and the invocation:
if (ConnectEvent != null)
{
ConnectEvent(this, new ConnectEventArgs(isConnected, message));
}
Define the event as:
public event ConnectEventHandler ConnectEvent = delegate{};
and remove the event to get thread safety.
I would reduce the run loop to:
private void Run()
{
while (true)
{
m_WaitHandle.WaitOne();
Event task = null;
lock (m_Locker)
{
if (m_Tasks.Count == 0)
{
m_WaitHandle.Reset();
continue;
}
task = m_Tasks.Dequeue();
}
task.DoTask(m_Manager);
}
}
The loop will continue to run until the event is reset.
Make sure that no null items are inserted into the queue instead of checking for null.
You could simplify the producer-consumer pattern in the Client class by using BlockingCollection instead of a combination of an AutoResetEvent and plain old Queue.
The EnqueueTask method would look like:
public void EnqueueTask(Event task)
{
m_Queue.Add(task);
}
The Run method would look like:
public void Run()
{
while (true)
{
Event task = m_Queue.Take();
if (task == null)
{
return;
}
task.DoTask();
}
}
Ok, simple problem hopefully.
I have started to make a simple server for a simple MORPG game im making, the client connected, and then disconnects, simple, the server catches the new client, but doesn't catch when it disconnects, whats wrong?
Im hoping its something stupidly obvious.
Here's my server code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.IO;
using System.Threading;
namespace ChaWilPeiBle
{
public partial class MainForm : Form
{
public bool ServerON = false;
public TcpListener ServerL;
public int ServerLoad = 2;
public string ServerINFtxt = "";
public ASCIIEncoding AE = new ASCIIEncoding();
public MainForm()
{
InitializeComponent();
}
private void LBL_SS_Click(object sender, EventArgs e)
{
}
private void MainForm_Load(object sender, EventArgs e)
{
LBL_SS.ForeColor = Color.Red;
}
public void AddH(string S)
{
ServerINFtxt += S;
}
public void Server()
{
try
{
ServerL = new TcpListener(47);
ServerL.Start();
AddH("\nServer Started On Port 47");
}
catch(Exception e)
{
MessageBox.Show("Error starting Server.__________________\n"+e.ToString());
}
while (true)
{
TcpClient TCPC;
TCPC = ServerL.AcceptTcpClient();
if (ServerLoad < 100)
{
Thread T = new Thread(HandleClient);
T.Start((object)TCPC);
}
else
{
byte[] BYTES = AE.GetBytes("NoAccess:Full");
NetworkStream NS = TCPC.GetStream();
NS.Write(BYTES, 0, BYTES.Length);
}
}
}
public void HandleClient(object C)
{
ServerLoad++;
TcpClient Client = (TcpClient)C;
NetworkStream NS = Client.GetStream();
AddH("Client Connected.\nServer Load: " + ServerLoad);
Thread T = new Thread(ReadClient);
T.Start(C);
try
{
while (true) { NS.Write(AE.GetBytes(""), 0, AE.GetBytes("").Length); }
}
catch { }
ServerLoad--;
AddH("Client Disconnected.\nServer Load: " + ServerLoad);
}
public void ReadClient(object C)
{
//TcpClient Client = (TcpClient)C;
}
private void startStopToolStripMenuItem_Click(object sender, EventArgs e)
{
LBL_SS.Text = "Server On";
LBL_SS.ForeColor = Color.Green;
if (ServerON == false)
{
Thread T = new Thread(Server);
T.Start();
}
ServerON = true;
}
private void Update_Tick(object sender, EventArgs e)
{
ServerINF.Text = ServerINFtxt;
PB_SL.Value = ServerLoad;
}
}
}
If you make a blocking call to read on a network stream and it returns 0 bytes as the length that it read it means that your client has disconnected. You will not get an exception until you try write to this connection. That's my best guess as to what is happening.