Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 5941295
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 22, 20262026-05-22T16:05:23+00:00 2026-05-22T16:05:23+00:00

I’ve opened a socket between two machines. On both ends, they call BeginReceive and

  • 0

I’ve opened a socket between two machines. On both ends, they call BeginReceive and wait for each other to send data. Either one could send data first, it depends on the user.

I’m finding that I cannot send data both ways, and only the app that initiated the connection can send data.

Edit: Added code for File Tunnel program; added comment showing where I messed up

//-----------Main.cs file------------
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.Threading;
using System.Net;
using System.IO;

public Socket listen_socket = null; //Listening socket (activated by clicking a button)
public List<Socket> connections = new List<Socket>(); //Stores all active connections to other server/client hybrids
public List<FileReceiver> receivers = new List<FileReceiver>(); //One FileReceiver for each active connection, handles receiving files on the connection
public List<FileSender> senders = new List<FileSender>(); //One FileSender per connection when a file is dropped in the interface, handles sending the file to each connected instance
public Queue<string> files_to_send = new Queue<string>(); //Queues files to send, if multiple files are dropped in the interface at once

public Main()
{
    InitializeComponent();
    Application.ApplicationExit += new EventHandler(Application_ApplicationExit);
    lstFiles.DragEnter += new DragEventHandler(lstFiles_DragEnter);
    lstFiles.DragDrop += new DragEventHandler(lstFiles_DragDrop);
}

private void lstFiles_DragEnter(object sender, DragEventArgs e)
{
    e.Effect = DragDropEffects.All;
}

void lstFiles_DragDrop(object sender, DragEventArgs e)
{
    string[] filepaths = e.Data.GetData( DataFormats.FileDrop ) as string[];
    if (filepaths != null)
    {
        lock (files_to_send)
        {
            foreach (string filepath in filepaths)
                files_to_send.Enqueue( filepath );
            SendNextFile();
        }
    }
}

void SendNextFile()
{
    lock (files_to_send)
    {
        if (senders.Count == 0 && files_to_send.Count > 0)
        {
            string filepath = files_to_send.Dequeue();
            FileInfo fi = new FileInfo( filepath );
            string filename = fi.Name;

            MemoryStream ms = new MemoryStream();
            BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode );
            writer.Write( (int)filename.Length ); //known-length (4 bytes); serves as hint to protocol so it doesn't try to read string until it knows enough data has been received
            writer.Write( filename ); //known length once previous int has been read
            writer.Write( fi.CreationTimeUtc.ToBinary() ); //known-length (8 bytes)
            writer.Write( fi.LastWriteTimeUtc.ToBinary() ); //known-length (8 bytes)
            writer.Write( fi.LastAccessTimeUtc.ToBinary() ); //known-length (8 bytes)
            writer.Write( (long)fi.Length ); //known-length (8 bytes)
            byte[] header = ms.ToArray();

            foreach (Socket socket in connections)
            {
                FileSender filesender = new FileSender( fi, header, socket );
                filesender.SendComplete += new FileSenderCompletedEventHandler(filesender_SendComplete);
                senders.Add( filesender );
            }
        }
    }
}

void filesender_SendComplete(FileSender sender)
{
    lock (files_to_send)
    {
        senders.Remove( sender );
        if (senders.Count == 0)
            SendNextFile();
    }
    if (!sender.CompletedSuccessfully)
        MessageBox.Show( "Failed to send " + sender.fi.FullName + " to " + sender.socket.RemoteEndPoint.ToString() );
}

void Application_ApplicationExit(object sender, EventArgs e)
{
    lock (connections)
    {
        foreach (Socket socket in connections)
        {
            try
            {
                socket.Shutdown( SocketShutdown.Both );
                socket.Close();
            }
            catch (Exception err)
            {
            }
        }
        connections.Clear();
    }
}

private void btnListen_Click(object sender, EventArgs e)
{
    try
    {
        btnListen.Enabled = false;
        if (listen_socket != null)
            listen_socket.Close();
        listen_socket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        listen_socket.Bind( new IPEndPoint( IPAddress.Any, int.Parse( txtListenPort.Text.Trim() ) ) );
        listen_socket.Listen( 1 );
        listen_socket.BeginAccept( new AsyncCallback( handleAccept ), listen_socket );
    }
    catch (Exception err)
    {
        MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
        btnListen.Enabled = true;
        if (listen_socket != null)
            listen_socket.Close();
    }
}

//INITIALIZES CONNECTION ON LISTENING END
private void BeginAccept_Callback( IAsyncResult result )
{
    Socket listen_socket = result.AsyncState as Socket;
    try
    {
        Socket connection = listen_socket.EndAccept( result );
        lock (connections)
        {
            ConfigureSocket( connection );
            FileReceiver receiver = AddSocketConnection( connection );
            receiver.receiveData(); //<--WAS MISSING THIS!!! Initiates asynchronous BeginReceive call; FileReceiver handles processing the incoming stream as it arrives.
        }
    }
    catch (Exception err)
    {
        MessageBox.Show( err.Message );
    }
    listen_socket.Close();
}

private void btnConnect_Click(object sender, EventArgs e)
{
    string[] a = txtConnectIP.Text.Split( '.' );
    IPAddress address = new IPAddress( new byte[] {byte.Parse( a[0] ), byte.Parse( a[1] ), byte.Parse( a[2] ), byte.Parse( a[3] ) } );
    int port = int.Parse( txtConnectPort.Text );
    Connect( address, port );
}

//INITIALIZES CONNECTION ON CONNECTING END
private void Connect( IPAddress address, int port )
{
    Socket connection = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
    lock (connections)
    {
        try
        {
            ConfigureSocket( connection );
            connection.Connect( address, port );
            FileReceiver receiver = AddSocketConnection( connection );
            receiver.receiveData(); //<--REMEMBERED IT HERE!!! So I could receive files on the connecting end.
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message );
        }
    }
}

private void DisplayConnectionsCount( int count )
{
    txtConnections.Text = count.ToString();
}

private void ConfigureSocket( Socket connection )
{
    connection.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true );
    connection.UseOnlyOverlappedIO = true;
    connection.LingerState = new LingerOption( false, 0 );
}

private FileReceiver AddSocketConnection( Socket connection )
{
    lock (connections)
    {
        connections.Add( connection );
        Invoke( new Action<string>( DisplayConnectionCount ), connections.Count );
        FileReceiver receiver = new FileReceiver( connection );
        receivers.Add( receiver );
        receiver.ReceiverShutdown += new FileReceiverShutdownEventHandler( receiver_Shutdown );
        receiver.FileReceived += new FileReceiverReceiveEventHandler(receiver_FileReceived);
        receiver.ReceiverDownloading += new FileReceiverDownloadingEventHandler(receiver_ReceiverDownloading);
        return receiver;
    }
}

private void RemoveSocketConnection( FileReceiver receiver )
{
    lock (connections)
    {
        try
        {
            receiver.ReceiverShutdown -= new FileReceiverShutdownEventHandler( receiver_Shutdown );
            receiver.FileReceived -= new FileReceiverReceiveEventHandler(receiver_FileReceived);
            receiver.ReceiverDownloading -= new FileReceiverDownloadingEventHandler(receiver_ReceiverDownloading);
            receivers.Remove( receiver );
            connections.Remove( receiver.connection );
            Invoke( new Action<int>( DisplayConnectionsCount ), connections.Count );
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
        }
    }
}

void receiver_ReceiverDownloading(FileReceiver receiver)
{
    if (InvokeRequired)
        Invoke( new FileReceiverDownloadingEventHandler( receiver_ReceiverDownloading ), receiver );
    else
        Text = "File Tunnel - Received " + receiver.BytesReceived + " bytes...";
}

void receiver_FileReceived(FileInfo fi)
{
    if (lstFiles.InvokeRequired)
        lstFiles.BeginInvoke( new FileReceiverReceiveEventHandler( receiver_FileReceived ), fi );
    else
    {
        lstFiles.Items.Add( fi );
        Text = "File Tunnel";
    }
}

public void receiver_Shutdown( FileReceiver receiver )
{
    RemoveSocketConnection( receiver );
}

//----FileSender.cs file------
public delegate void FileSenderCompletedEventHandler( FileSender sender );
public class FileSender
{
    public Socket socket;
    public FileInfo fi;
    public FileStream fs;

    public event FileSenderCompletedEventHandler SendComplete;
    private byte[] header;
    public bool CompletedSuccessfully = false;

    public FileSender( FileInfo fi, byte[] header, Socket socket )
    {
        this.fi = fi;
        this.socket = socket;
        this.header = header;
        try
        {
            socket.BeginSendFile( fi.FullName, header, null, TransmitFileOptions.UseSystemThread, new AsyncCallback( send_File ), this );
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
            CompleteCallback();
        }
    }

    private void send_File( IAsyncResult result )
    {
        try
        {
            socket.EndSendFile( result );
            CompletedSuccessfully = true;
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
        }
        finally
        {
            CompleteCallback();
        }
    }

    private void CompleteCallback()
    {
        try
        {
            if (SendComplete != null)
                SendComplete( this );
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
        }
    }
}


//----FileReceiver.cs file------
public delegate void FileReceiverReceiveEventHandler( FileInfo fi );
public delegate void FileReceiverShutdownEventHandler( FileReceiver receiver );
public delegate void FileReceiverDownloadingEventHandler( FileReceiver receiver );

public enum FileReceiverProtocolStep
{
    ReadFilenameLength,
    ReadFilename,
    ReadTimestamps,
    ReadFileLength,
    ReadFile
}

public class FileReceiver
{
    public const int BUFFER_SIZE = 1024 * 1024;
    public Socket connection;
    private byte[] buffer = new byte[BUFFER_SIZE];

    private long last_read_position = 0;
    private FileReceiverProtocolStep protocol_step = FileReceiverProtocolStep.ReadFilenameLength;

    private MemoryStream received_data = new MemoryStream();

    public event FileReceiverReceiveEventHandler FileReceived;
    public event FileReceiverShutdownEventHandler ReceiverShutdown;
    public event FileReceiverDownloadingEventHandler ReceiverDownloading;

    public FileReceiver( Socket connection )
    {
        this.connection = connection;
    }

    public long BytesReceived
    {
        get {return received_data.Length;}
    }

    public void receiveData()
    {
        connection.BeginReceive( buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback( receiveDataCallback ), connection );
    }

    private void receiveDataCallback( IAsyncResult result )
    {
        Socket connection = result.AsyncState as Socket;
        int bytes_read;

        try
        {
            bytes_read = connection.EndReceive( result );
            if (bytes_read == 0)
            {
                if (received_data.Length > 0)
                    ProcessMemoryStream();
                else
                {
                    ShutDown(); //Nothing recieved... socket probably closed
                    return;
                }
            }
            else
            {
                lock (received_data)
                    received_data.Write( buffer, 0, bytes_read );
                ProcessMemoryStream(); //Process as much of the memory stream as possible
                if (ReceiverDownloading != null)
                    ReceiverDownloading( this );
            }
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
            ShutDown();
            return;
        }

        receiveData();
    }

    private void ShutDown()
    {
        try
        {
            connection.Shutdown( SocketShutdown.Both );
            connection.Close();
        }
        catch (Exception err)
        {
            MessageBox.Show( err.Message + "\r\n" + err.StackTrace );
        }

        if (ReceiverShutdown != null)
            ReceiverShutdown( this );
    }

    private int filename_length;
    private string filename;
    private DateTime timestamp_creation;
    private DateTime timestamp_modified;
    private DateTime timestamp_lastaccess;
    long file_length;

    private void ProcessMemoryStream()
    {
        //Prepare binary reader
        lock (received_data)
        {
            BinaryReader reader = new BinaryReader( received_data, Encoding.Unicode );
            received_data.Position = last_read_position;

        next_step:
            long bytes_available = received_data.Length - received_data.Position;
            switch (protocol_step)
            {
                case FileReceiverProtocolStep.ReadFilenameLength:
                    //Read filename
                    if (bytes_available >= 4)
                    {
                        filename_length = reader.ReadInt32();
                        protocol_step = FileReceiverProtocolStep.ReadFilename;
                        goto next_step;
                    }
                    break;
                case FileReceiverProtocolStep.ReadFilename:
                    if (bytes_available >= filename_length)
                    {
                        filename = reader.ReadString();
                        protocol_step = FileReceiverProtocolStep.ReadTimestamps;
                        goto next_step;
                    }
                    break;
                case FileReceiverProtocolStep.ReadTimestamps:
                    if (bytes_available >= 24)
                    {
                        //Read timestamps
                        timestamp_creation = DateTime.FromBinary( reader.ReadInt64() );
                        timestamp_modified = DateTime.FromBinary( reader.ReadInt64() );
                        timestamp_lastaccess = DateTime.FromBinary( reader.ReadInt64() );
                        protocol_step = FileReceiverProtocolStep.ReadFileLength;
                        goto next_step;
                    }
                    break;
                case FileReceiverProtocolStep.ReadFileLength:
                    if (bytes_available >= 8)
                    {
                        file_length = reader.ReadInt64();
                        protocol_step = FileReceiverProtocolStep.ReadFile;
                        goto next_step;
                    }
                    break;
                case FileReceiverProtocolStep.ReadFile:
                    if (bytes_available >= file_length)
                    {
                        FileInfo fi = new FileInfo( filename.Replace( '\\', '_' ).Replace( '/', '_' ) ); //Disable relative path specification
                        FileStream fs = fi.Open( FileMode.Create, FileAccess.Write, FileShare.Read );
                        long bytes_to_save = file_length;
                        while (bytes_to_save > 0)
                        {
                            int bytes_to_read = (int)Math.Min( (long)BUFFER_SIZE, bytes_to_save );
                            bytes_to_save -= bytes_to_read;
                            fs.Write( reader.ReadBytes( bytes_to_read ), 0, bytes_to_read );
                        }
                        fs.Close();
                        fi.CreationTimeUtc = timestamp_creation;
                        fi.LastWriteTimeUtc = timestamp_modified;
                        fi.LastAccessTimeUtc = timestamp_lastaccess;

                        received_data.Position = 0;
                        received_data.SetLength( 0 );

                        //Reset protocol for next file
                        protocol_step = FileReceiverProtocolStep.ReadFilenameLength; //Ready for next file
                        filename_length = 0;
                        filename = String.Empty;
                        timestamp_creation = DateTime.MinValue;
                        timestamp_modified = DateTime.MinValue;
                        timestamp_lastaccess = DateTime.MinValue;
                        file_length = 0;

                        if (FileReceived != null)
                            FileReceived( fi );
                    }
                    break;
            }

            //Backup the last read position, and set the position to the end of the stream for subsquent write operations
            last_read_position = received_data.Position;
            received_data.Seek( 0, SeekOrigin.End );
        }
    }
}

So that’s the code for now. Excuse any sloppyness in this code, I wrote it as fast as possible, but that’s the entire program at this point, and it’s fully functional (Main.cs, FileReceiver.cs, and FileSender.cs). The Form consists of a listBox, and a few buttons and text boxes. The feedback is extremely basic at this point (displays bytes received in the titlebar as it’s receiving the file). Eventually, I’ll have it parse the IP addresses with RegExes with realtime feedback, accept hostnames with DNS resolvers, I’ll replace the listbox with an explorer-style list view, have it store things in a special directory, allow files to be dragged/moved into explorer, etc., etc.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-22T16:05:24+00:00Added an answer on May 22, 2026 at 4:05 pm

    I was not calling BeginReceive in the code that accepts the connection on the listening end (see comment in BeginAccept_Callback method in posted code.)

    I can say with certainty now, that one can call BeginReceive on a socket and call the BeginSend* methods on it as well at any time, so one can receive and send data simultaneously over a single Socket.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
Basically, what I'm trying to create is a page of div tags, each has
I'm using v2.0 of ClassTextile.php, with the following call: $testimonial_text = $textile->TextileRestricted($_POST['testimonial']); ... and
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I am writing an app with both english and french support. The app requests
I'm having trouble keeping the paragraph square between the quote marks. In firefox the
I am using Paperclip to handle profile photo uploads in my app. They upload
That's pretty much it. I'm using Nokogiri to scrape a web page what has
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.