Today you will notice that with most instant messengers everyone connects to a central server which routes all of the messages. Way back when ICQ used to do p2p where you would connect to the other persons computer to send them an IM. As people started implementing firewalls this became very problematic so it is almost standard to use a central operating server for no purpose other than to switch packets.
//netStream is a network stream object from a tcpClient connection //this sends the entire byte array all at once. byte[] outStream = System.Text.Encoding.ASCII.GetBytes("some text to send"); netStream.Write(outStream, 0, outStream.Length); netStream.Flush(); //server side //clientSocket here is a TCPClient object //fills bytearray with stream data in one read byte[] bytesFrom = new byte[10240];//10k byte array networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
sk@sk:~$ /sbin/ifconfig eth0 | grep -i mtu
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.IO; using System.Runtime.Remoting.Messaging; namespace Client { public delegate void OnSendFileCompleteDelegate(object sender, SendFileCompleteEventArgs e); public class SendFileCompleteEventArgs : EventArgs { private string _fileName; private DateTime _started; private DateTime _completed; public string FileName { get { return _fileName; } } public DateTime Started { get { return _started; } internal set { _started = value; } } public DateTime Completed { get { return _completed; } internal set { _completed = value; } } public TimeSpan TimeTaken { get { return this.Completed.Subtract(this.Started); } } private SendFileCompleteEventArgs() : this(string.Empty) { } public SendFileCompleteEventArgs(string FileName) { this._fileName = FileName; } } public class ClientStuff { public const int DEFAULT_SERVER_PORT = 30043; private IPEndPoint endPoint; public event OnSendFileCompleteDelegate OnSendFileComplete; private ClientStuff() { } public ClientStuff(string IP, int Port) : this(IPAddress.Parse(IP), Port) { } public ClientStuff(IPAddress IP, int Port) : this(new IPEndPoint(IP, Port)) { } public ClientStuff(IPEndPoint EndPoint) : this() { if (EndPoint == null) throw new ArgumentNullException("EndPoint"); this.endPoint = EndPoint; } public void SendFile(string FileName) { new Func<string, SendFileCompleteEventArgs>(SendFileWorker).BeginInvoke( FileName, new AsyncCallback(SendFileCallback), null); } private SendFileCompleteEventArgs SendFileWorker(string FileName) { SendFileCompleteEventArgs result = null; using (FileStream fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (TcpClient cli = new TcpClient()) { cli.Connect(this.endPoint); result = new SendFileCompleteEventArgs(FileName); result.Started = DateTime.Now; using (NetworkStream ns = cli.GetStream()) { StreamHelper.CopyStreamToStream(fs, ns, null); ns.Flush(); ns.Close(); } result.Completed = DateTime.Now; return result; } } } private void SendFileCallback(IAsyncResult ar) { AsyncResult result = (AsyncResult)ar; Func<string, SendFileCompleteEventArgs> del = (Func<string, SendFileCompleteEventArgs>)result.AsyncDelegate; try { SendFileCompleteEventArgs args = del.EndInvoke(ar); if (args != null) { var evt = this.OnSendFileComplete; if (evt != null) evt(this, args); } } catch { throw; //handle this } } } }
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; namespace Client { public partial class frmClient : Form { private ClientStuff client; public frmClient() { InitializeComponent(); } private void frmClient_Load(object sender, EventArgs e) { StartClient(); this.Location = new Point(0, 0); } private void StartClient() { if (client != null) throw new InvalidOperationException("Client is already running"); client = new ClientStuff(IPAddress.Loopback, ClientStuff.DEFAULT_SERVER_PORT); client.OnSendFileComplete += new OnSendFileCompleteDelegate(client_OnSendFileComplete); } private void StopClient() { //I didn't add stop support for the client if (client != null) { client = null; } } void client_OnSendFileComplete(object sender, SendFileCompleteEventArgs e) { if (this.InvokeRequired) { this.Invoke(new OnSendFileCompleteDelegate(client_OnSendFileComplete), sender, e); } else { MessageBox.Show( string.Format("Sent file {0} in {1}", e.FileName, e.TimeTaken), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Information); } } private void button1_Click(object sender, EventArgs e) { if (openFileDialog1.ShowDialog() == DialogResult.OK) { client.SendFile(openFileDialog1.FileName); } } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Net; using System.IO; using System.Threading; using System.Runtime.Remoting.Messaging; namespace Server { #region event stuff public delegate void OnFileReceivedDelegate(object sender, OnFileReceivedArgs e); public class OnFileReceivedArgs : EventArgs { private byte[] _buffer; public byte[] Buffer { get { return _buffer; } } private OnFileReceivedArgs() : base() { } public OnFileReceivedArgs(byte[] buffer) : this() { this._buffer = buffer; } } #endregion public class ServerStuff : IDisposable { public const int DEFAULT_SERVER_PORT = 30043; private TcpListener listener; private List<WeakReference> connections; //dont want our handy conn list to stop garbage collection public event OnFileReceivedDelegate OnFileReceived; public int ConnectionCount { get { lock (connections) { return connections.Count; } } } private ServerStuff() : this(DEFAULT_SERVER_PORT) { } public ServerStuff(int Port) { connections = new List<WeakReference>(); listener = new TcpListener(IPAddress.Any, DEFAULT_SERVER_PORT); } public void Start() { listener.Start(); listener.BeginAcceptSocket(new AsyncCallback(ConnectionCallback), listener); } public void Stop() { listener.Stop(); KillRunningThreads(); } private void TrackThread() { lock (connections) { connections.Add(new WeakReference(Thread.CurrentThread, false)); } } private void RemoveThread() { Thread t = Thread.CurrentThread; lock (connections) { for (int i1 = 0; i1 < connections.Count; i1++) { if ((connections[i1].Target as Thread) == t) { connections.RemoveAt(i1); break; } } } } private Thread[] GetRunningThreads() { lock (connections) { List<Thread> result = new List<Thread>(); foreach (WeakReference wr in connections) { if (wr.IsAlive) result.Add((Thread)wr.Target); } return result.ToArray(); } } private void KillRunningThreads() { Thread[] threads = GetRunningThreads(); foreach (Thread t in threads) { try { t.Abort(); } catch { } } } private void ConnectionCallback(IAsyncResult ar) { TcpListener listener = (TcpListener)ar.AsyncState; try { Socket s = listener.EndAcceptSocket(ar); new Func<Socket, byte[]>(HandleSocketComms).BeginInvoke( s, new AsyncCallback(HandleSocketCommsCallback), s); } catch { //You should handle this but this should be a _rare_ error throw; } finally { //Prime up the listener to accept another inbound request listener.BeginAcceptSocket(new AsyncCallback(ConnectionCallback), listener); } } /// <summary> /// This basically blocks until the socket closes and we have /// received all of the data /// </summary> /// <param name="s"></param> /// <returns></returns> private byte[] HandleSocketComms(Socket s) { //Dont do any exception handling here TrackThread(); using (MemoryStream ms = new MemoryStream()) //This may be a bad idea for big files :) { do { int szToRead = s.Available; byte[] buffer = new byte[szToRead]; int szRead = s.Receive(buffer, szToRead, SocketFlags.None); if (szRead > 0) { ms.Write(buffer, 0, szRead); Console.WriteLine("Read " + szRead.ToString()); } } while (SocketConnected(s)); return ms.ToArray(); } //return result; } private static bool SocketConnected(Socket s) { return !(s.Poll(1000, SelectMode.SelectRead) && (s.Available == 0)); } private void HandleSocketCommsCallback(IAsyncResult ar) { byte[] file = null; bool error = false; try { AsyncResult result = (AsyncResult)ar; var del = (Func<Socket, byte[]>)result.AsyncDelegate; file = del.EndInvoke(ar); Socket s = (ar.AsyncState as Socket); if (s != null) { //Sockets throw exceptions++ when disposed try { s.Close(0); ((IDisposable)s).Dispose(); } catch { } } } catch (ThreadAbortException) //When we stop our server { //We were killed! Just let it die out error = true; } catch { //Might want to handle this error = true; } finally { RemoveThread(); //conn is closed at this point if (!error && (file != null) && (file.Length > 0)) { var del = this.OnFileReceived; if (del != null) del(this, new OnFileReceivedArgs(file)); } } } #region IDisposable Members public void Dispose() { if (listener != null) { listener.Stop(); listener = null; } KillRunningThreads(); } #endregion } }
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.IO; using System.Diagnostics; namespace Server { public partial class frmServer : Form { private ServerStuff server; public frmServer() { InitializeComponent(); } private void StartServer() { if (server != null) throw new InvalidOperationException("Server is already running"); server = new ServerStuff(ServerStuff.DEFAULT_SERVER_PORT); server.Start(); server.OnFileReceived += new OnFileReceivedDelegate(server_OnFileReceived); } private void StopServer() { if (server != null) { server.OnFileReceived -= new OnFileReceivedDelegate(server_OnFileReceived); server.Stop(); ((IDisposable)server).Dispose(); server = null; } } void server_OnFileReceived(object sender, OnFileReceivedArgs e) { if (this.InvokeRequired) { //Just in case we want to play with the UI this.Invoke(new OnFileReceivedDelegate(server_OnFileReceived), sender, e); } else { string tmpFile = Path.GetTempFileName(); #region change the extension { string newFile = Path.ChangeExtension(tmpFile, ".bmp"); File.Move(tmpFile, newFile); tmpFile = newFile; } #endregion File.WriteAllBytes(tmpFile, e.Buffer); Process p = Process.Start(tmpFile); p.WaitForExit(); File.Delete(tmpFile); } } private void frmServer_Load(object sender, EventArgs e) { StartServer(); this.Location = new Point(SystemInformation.WorkingArea.Width - this.Width, 0); } private void button1_Click(object sender, EventArgs e) { //byte[] b = File.ReadAllBytes(@"C:\img\dw\desktop.bmp"); //System.Diagnostics.Debugger.Break(); //6912054 } } }
TCPMSS
This target allows to alter the MSS value of TCP SYN packets, to control the maximum size for that connection (usually limiting it to your outgoing interface's MTU minus 40). Of course, it can only be used in conjunction
with -p tcp. It is only valid in the mangle table.
This target is used to overcome criminally braindead ISPs or servers which block ICMP Fragmentation Needed packets. The symptoms of this problem are that everything works fine from your Linux firewall/router, but machines
behind it can never exchange large packets:
1) Web browsers connect, then hang with no data received.
2) Small mail works fine, but large emails hang.
3) ssh works fine, but scp hangs after initial handshaking.
Workaround: activate this option and add a rule to your firewall configuration like:
iptables -t mangle -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --clamp-mss-to-pmtu

| DaniWeb Message | |
| Cancel Changes | |