Hello everybody,

I am using Serial COM Simply in C# by Noah Coad
http://www.devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=320

and I have available ports on my machine whichs
COM1,COM2,COM6,COM7,COM8,COM9,COM10,COM11,COM12,COM13
and I use COM6,COM7,COM8,COM9,COM10,COM11,COM12 with
ZyXEL Omni 56K modem, I use these 7 ports with 7 modems.
There are clients for getting answer wtih this modems.
I use the mscomm.ocx to listen com ports. My application
is running successfully but sometimes one modem processing
50-100 ruqest and answer then it stops its working and
my clients getting time out because they do not get the answer
from server(using com port modem). First it getting "RING" and then
getting "CONNECT 1200/V.22b 2400/NONE" then getting orginal package
of my client and I process this package and produce a answer to client.
I use 7 exe files for open and listen com ports because when I use
1 exe file I do not process same time. I know I must use Thread but I dont know.
Please help me, How can I listen 7 com port same time and doing my work with no
problems. Always I want to my application work correctly and reply to all clients
in same time. These is my codes :

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Threading;

namespace Serial_Demo
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Label label8;

        private Sistem sistemim = new Sistem();
        private ParcaKontorRaporu parcaKontorRaporu = new ParcaKontorRaporu();
        private ParcaKontorYukleme parcaKontorYukleme = new ParcaKontorYukleme();
        private FaturaOdeme faturaOdeme = new FaturaOdeme();
        private FaturaRaporu faturaRaporu = new FaturaRaporu();
        private FaturaSorgulama faturaSorgulama = new FaturaSorgulama();
        private NumaraSorgulama numaraSorgulama = new NumaraSorgulama();
        private TamKontorRaporu tamKontorRaporu = new TamKontorRaporu();
        private TamKontorYükleme tamKontorYukleme = new TamKontorYükleme();
        private BakiyeSorgulama bakiyeSorgulama = new BakiyeSorgulama();
        private HavaleBildirimi havale = new HavaleBildirimi();
        private KartKontorSifresi kartSifresi = new KartKontorSifresi();
        private KartKontorRaporu kartRapor = new KartKontorRaporu();
        private FiyatListesi fiyatListesi = new FiyatListesi();
        private AylikKontorRaporu aylikKontorRapor = new AylikKontorRaporu();
        private AylikFaturaRaporu aylikFaturaRapor = new AylikFaturaRaporu();
        private SifreDegirtirme sifreDegistir = new SifreDegirtirme();
        private BankaExtra BankExtra = new BankaExtra();
        private Duyurular duyuru = new Duyurular();
        private DuyurularExtra duyuruExtra = new DuyurularExtra();
        private BankaListesi Bankalar = new BankaListesi();
        private KontorFiyatSorgula KontorFiyat = new KontorFiyatSorgula();

        string bugun = DateTime.Now.ToShortDateString();
        private AxMSCommLib.AxMSComm com;
        private Button btn_disconnect;
        private Label label1;
        private Panel panel1;
        string GidenToPos = null;
        private int count = 0;
        private IContainer components;
        private System.Windows.Forms.Timer timer1;
        private ListBox listBox1;
        private Label sayiLbl;
        private Label label2;
        Char chr = (char)13;

        public Form1()
        {
            InitializeComponent();

            InitComPort();
        }

        private void InitComPort()
        {     
            // Set the com port to be 1
            com.CommPort = 6;

            // This port is already open, then close.
            if (com.PortOpen)
                com.PortOpen = false;

            // Trigger the OnComm event whenever data is received
            com.RThreshold = 1;

            // Set the port to 9600 baud, no parity bit, 8 data bits, 1 stop bit (all standard)
            com.Settings = "1200,n,8,1";

            // Force the DTR line high, used sometimes to hang up modems
            //com.DTREnable = true;

            com.RTSEnable = true;

            com.DTREnable = true;

            // No handshaking is used
            com.Handshaking = MSCommLib.HandshakeConstants.comNone;

            // Use this line instead for byte array input, best for most communications
            com.InputMode = MSCommLib.InputModeConstants.comInputModeText;

            // Read the entire waiting data when com.Input is used
            com.InputLen = 0;

            // Don't discard nulls, 0x00 is a useful byte
            com.NullDiscard = false;

            // Attach the event handler
            com.OnComm += new System.EventHandler(this.OnComm);

            com.PortOpen = true;

            com.Output = "AT&F S0=1" + chr;
            com.Output = "ATM0" + chr;
            com.Output = "ATS7=90 +++ATH0" + chr;

        }
    
        private void OnComm(object sender, EventArgs e)  //  MSCommLib OnComm Event Handler
        {
           Thread.Sleep(400);

            if (com.InBufferCount > 0) 
            {
                string response = (string)com.Input;

                ProcessResponseText(response);
            }
            com.PortOpen = true;
        }

        private void ProcessResponseText(string input)
        {
            string IslemSaati = DateTime.Now.ToShortTimeString();

            if (input.Trim().Equals("RING"))
            {
                listBox1.Items.Add(IslemSaati + " - ringing...");
            }
            else
                if (input.Trim().Equals("CONNECT 1200/V.22b 2400/NONE"))
                {
                    listBox1.Items.Add(IslemSaati + " - connecting...");

                }
                else
                {
                    char[] c = input.Trim().ToCharArray();
                    if (c[0].ToString() == "\x02")
                    {
                        count++;
                        sayiLbl.Text = "number of process : " + Convert.ToString(count);

                        string gidecekStr = null;
                        gidecekStr = GeleniTemizle(input);
                        GidenToPos = null;

                        char[] k = gidecekStr.ToCharArray();

                        if (k[0].ToString() == "X")
                        {
                            for (int i = 1; i < k.Length; i++)
                            {
                                GidenToPos += k[i];
                            }
                        }
                        else
                        {
                            GidenToPos = paketFiltre(gidecekStr);
                        }

                        listBox1.Items.Add(IslemSaati + " - Coming Package : " + input);

                        com.Output = GidenToPos;

                        listBox1.Items.Add(IslemSaati + " - Going Package : " + GidenToPos);
                    }
                    else
                    {
                        sayiLbl.Text = "number of process : " + Convert.ToString(count);
                    }
                }
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {

            }
            base.Dispose(disposing);
        }

        public string paketFiltre(string gelen)
        {
            char[] c = gelen.ToCharArray();
            string gidecekStr = null;
            int secim = 0;

            if (c[18].ToString() == "1")
            {
                secim = 1;
            }
            if (c[18].ToString() == "2")
            {
                secim = 2;
            }
            if (c[18].ToString() == "3")
            {
                secim = 3;
            }
            if (c[18].ToString() == "4")
            {
                secim = 4;
            }
            if (c[18].ToString() == "5")
            {
                secim = 5;
            }
            if (c[18].ToString() == "6")
            {
                secim = 6;
            }
            if (c[18].ToString() == "7")
            {
                secim = 7;
            }
            if (c[18].ToString() == "8")
            {
                secim = 8;
            }
            if (c[18].ToString() == "9")
            {
                secim = 9;
            }
            if (c[18].ToString() == "A")
            {
                secim = 10;
            }
            if (c[18].ToString() == "B")
            {
                secim = 11;
            }
            if (c[18].ToString() == "C")
            {
                secim = 12;
            }
            if (c[18].ToString() == "D")
            {
                secim = 13;
            }
            if (c[18].ToString() == "E")
            {
                secim = 14;
            }
            if (c[18].ToString() == "F")
            {
                secim = 15;
            }
            if (c[18].ToString() == "G")
            {
                secim = 16;
            }
            if (c[18].ToString() == "H")
            {
                secim = 17;
            }
            if (c[18].ToString() == "I")
            {
                secim = 18;
            }
            if (c[18].ToString() == "J")
            {
                secim = 19;
            }
            if (c[18].ToString() == "K")
            {
                secim = 20;
            }
            if (c[18].ToString() == "L")
            {
                secim = 21;
            }

            switch (secim)
            {
                case 1:  // Bakiye Sorgulama
                    gidecekStr = bakiyeSorgulama.BakiyeSorgula(gelen);
                    break;

                case 2:  // Parça Kontör Talimatı Gönderme
                    gidecekStr = parcaKontorYukleme.ParcaKontorYukle(gelen);
                    break;

                case 3: // Parça Kontör Raporu
                    gidecekStr = parcaKontorRaporu.Rapor(gelen);
                    break;

                case 4: // Tam Kontör Talimatı Gönderme
                    gidecekStr = tamKontorYukleme.KontorYukle(gelen);
                    break;

                case 5: // Tam Kontör Raporu
                    gidecekStr = tamKontorRaporu.Rapor(gelen);
                    break;

                case 6: // Numara Sorgulama
                    gidecekStr = numaraSorgulama.Sorgula(gelen);
                    break;

                case 7: // Fatura Sorgulama
                    gidecekStr = faturaSorgulama.Sorgulama(gelen);
                    break;

                case 8: // Fatura Ödeme
                    gidecekStr = faturaOdeme.FaturaOde(gelen);
                    break;

                case 9: // Fatura Raporu
                    gidecekStr = faturaRaporu.Rapor(gelen);
                    break;

                case 10: // HAVALE/EFT BİLDİRİMİ
                    gidecekStr = havale.HavaleEftBildirimi(gelen);
                    break;

                case 11: // KART KONTÖR ŞİFRESİ ALMA
                    gidecekStr = kartSifresi.KartKontorSifresiAlma(gelen);
                    break;

                case 12: // KART KONTÖR RAPORU
                    gidecekStr = kartRapor.Rapor(gelen);
                    break;

                case 13: // FİYAT LİSTESİ
                    gidecekStr = fiyatListesi.Liste(gelen);
                    break;

                case 14: // GÜNLÜK/HAFTALIK/AYLIK KONTÖR RAPORU ALMA
                    gidecekStr = aylikKontorRapor.Rapor(gelen);
                    break;

                case 15: // GÜNLÜK/HAFTALIK/AYLIK FATURA RAPORU ALMA
                    gidecekStr = aylikFaturaRapor.Rapor(gelen);
                    break;

                case 16: // ŞİFRE DEĞİŞTİRME
                    gidecekStr = sifreDegistir.SifreDegistir(gelen);
                    break;

                case 17: // BANKA LİSTESİ
                    gidecekStr = Bankalar.Liste(gelen);
                    break;

                case 18: // BANKA EXTRA
                    gidecekStr = BankExtra.Liste(gelen);
                    break;

                case 19: // DUYURULAR
                    gidecekStr = duyuru.Liste(gelen);
                    break;

                case 20: // DUYURULAR EXTRA
                    gidecekStr = duyuruExtra.Liste(gelen);
                    break;

                case 21: // KONTÖR FİYAT SORGULA
                    gidecekStr = KontorFiyat.Sorgula(gelen);
                    break;
            }
            return gidecekStr;
        }

        public string ConvertToHex(string asciiString)
        {
            string hex = "";
            foreach (char c in asciiString)
            {
                int tmp = c;
                hex += String.Format("{0:x2}", (uint)System.Convert.ToUInt32(tmp.ToString()));
            }
            return hex;
        }

        private string HexAsciiConvert(string hex)
        {

            StringBuilder sb = new StringBuilder();

            for (int i = 0; i <= hex.Length - 2; i += 2)
            {

                sb.Append(Convert.ToString(Convert.ToChar(Int32.Parse(hex.Substring(i, 2),

                System.Globalization.NumberStyles.HexNumber))));

            }

            return sb.ToString();

        }
        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.label8 = new System.Windows.Forms.Label();
            this.com = new AxMSCommLib.AxMSComm();
            this.btn_disconnect = new System.Windows.Forms.Button();
            this.label1 = new System.Windows.Forms.Label();
            this.panel1 = new System.Windows.Forms.Panel();
            this.label2 = new System.Windows.Forms.Label();
            this.sayiLbl = new System.Windows.Forms.Label();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.listBox1 = new System.Windows.Forms.ListBox();
            ((System.ComponentModel.ISupportInitialize)(this.com)).BeginInit();
            this.panel1.SuspendLayout();
            this.SuspendLayout();
            // 
            // label8
            // 
            this.label8.BackColor = System.Drawing.Color.Transparent;
            this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label8.ForeColor = System.Drawing.SystemColors.Highlight;
            this.label8.Location = new System.Drawing.Point(0, 109);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(160, 24);
            this.label8.TabIndex = 22;
            this.label8.Text = "Gelen/Giden Paketler :";
            // 
            // com
            // 
            this.com.Enabled = true;
            this.com.Location = new System.Drawing.Point(491, 109);
            this.com.Name = "com";
            this.com.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("com.OcxState")));
            this.com.Size = new System.Drawing.Size(38, 38);
            this.com.TabIndex = 14;
            // 
            // btn_disconnect
            // 
            this.btn_disconnect.Location = new System.Drawing.Point(533, 72);
            this.btn_disconnect.Name = "btn_disconnect";
            this.btn_disconnect.Size = new System.Drawing.Size(86, 23);
            this.btn_disconnect.TabIndex = 17;
            this.btn_disconnect.Text = "Bağlantıyı kes";
            this.btn_disconnect.Click += new System.EventHandler(this.btn_disconnect_Click);
            // 
            // label1
            // 
            this.label1.BackColor = System.Drawing.Color.Transparent;
            this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label1.ForeColor = System.Drawing.Color.Red;
            this.label1.Location = new System.Drawing.Point(251, 17);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(148, 24);
            this.label1.TabIndex = 24;
            this.label1.Text = "DARKOCEAN";
            // 
            // panel1
            // 
            this.panel1.BackColor = System.Drawing.SystemColors.ControlLight;
            this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.panel1.Controls.Add(this.label2);
            this.panel1.Controls.Add(this.sayiLbl);
            this.panel1.Controls.Add(this.label1);
            this.panel1.Controls.Add(this.btn_disconnect);
            this.panel1.Location = new System.Drawing.Point(0, 0);
            this.panel1.Name = "panel1";
            this.panel1.Size = new System.Drawing.Size(634, 104);
            this.panel1.TabIndex = 23;
            // 
            // label2
            // 
            this.label2.BackColor = System.Drawing.Color.Transparent;
            this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.label2.ForeColor = System.Drawing.Color.Red;
            this.label2.Location = new System.Drawing.Point(251, 41);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(133, 24);
            this.label2.TabIndex = 26;
            this.label2.Text = " MODEM - 2";
            // 
            // sayiLbl
            // 
            this.sayiLbl.AutoSize = true;
            this.sayiLbl.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
            this.sayiLbl.ForeColor = System.Drawing.Color.Navy;
            this.sayiLbl.Location = new System.Drawing.Point(11, 72);
            this.sayiLbl.Name = "sayiLbl";
            this.sayiLbl.Size = new System.Drawing.Size(0, 13);
            this.sayiLbl.TabIndex = 25;
            // 
            // listBox1
            // 
            this.listBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(162)));
            this.listBox1.FormattingEnabled = true;
            this.listBox1.Location = new System.Drawing.Point(0, 136);
            this.listBox1.Name = "listBox1";
            this.listBox1.ScrollAlwaysVisible = true;
            this.listBox1.Size = new System.Drawing.Size(634, 134);
            this.listBox1.TabIndex = 27;
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(632, 270);
            this.Controls.Add(this.listBox1);
            this.Controls.Add(this.panel1);
            this.Controls.Add(this.com);
            this.Controls.Add(this.label8);
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "DARKOCEAN";
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.com)).EndInit();
            this.panel1.ResumeLayout(false);
            this.panel1.PerformLayout();
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void btn_disconnect_Click(object sender, System.EventArgs e)
        {
            // If com port is open then close it 
            // to disconnect connection

            if (com.PortOpen)
            {
                com.PortOpen = false;
                MessageBox.Show("Disconnected...", this.Text,
                    MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        public string GeleniTemizle(string gelen)
        {
            string DATA = null;
            string LRC = null;

            string temp1 = gelen.Replace("\x02", "");
            string[] tempArray = temp1.Split('\x03');


            string kontrolLRC = "";

            string gelenLRC = tempArray[1];

            sbyte[] array;

            array = sistemim.PrepareLRCPacket(tempArray[0]);

            foreach (sbyte ch in array)
                LRC += Convert.ToChar(ch);

            kontrolLRC = LRC[LRC.Length - 1].ToString();

            if (gelenLRC == kontrolLRC )
            {
                DATA = tempArray[0];
            }
            else
            {
                sbyte[] array2;
                string LRC2 = null;

                array2 = sistemim.PrepareLRCPacket("000000000000215" + "package problem");
                DATA = null;

                foreach (sbyte ch2 in array2)
                    LRC2 += Convert.ToChar(ch2);

                DATA = "X" + LRC2;
            }

            return DATA;
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

    }
}

You have answered your own question really; each port needs to operate in its own thread. The only way you can have your application monitoring and answering on all the ports concurrently is to use a threaded approach.
There are numerous tutorials and articles about threading...google is your friend.

The article you noted is very old (about March 07, 2002) and using the mscomm.ocx is no longer necessary in .Net.
I have found the mscomm.ocx has problems with loosing packets and memory leakages.
There is a native .Net serial port System.IO.Ports.SerialPort that I would strongly recommend that you change over to.

Thank you very much for your answers, @Ryshad I am new in Thread and I dont know How can I do this.@Nick, I know it is very very old and I tried to use system.io.serial ports but I can not arrange to get "RING" and "CONNECT 1200/V.22b 2400/NONE" and the original client's package. Please please if you have a example project or codes about my working, please share it with me. I want to use normal system.io.serialport and the threading in my application. Have a nice day.

The below link shows using SerialPort with multithreading using the BackgroundWorker.
You should be able to adapt it to using the mscomm.ocx.
stackoverflow.com system-io-ports-serialport-and-multithreading
Not sure about the RING and CONNECT issue. Will do a bit of research and post if I find anything useful.

This link sugests that RING is possible using SerialPort as the OP is receiving this already.
stackoverflow.com system-io-ports-serialport-can-ioctl-serial-set-wait-mask-be-configured
Maybe you should try again.

Have you tried using Sysinternals Portmon to monitor what is going in/out the serial port (Portmon link found in above link).
I have used this before and it is very useful when diagnosing serial port issues.

When I researched my application problem, I must be check modem status because sometimes my modem hang up in OH status mean that OH lamp is lighting and the telephone line will not be closed, if I close and open the problem everything will be ok but I must be solve modem hang up problem and I must be clear the buffer in every my process. I must be know modem status and If I check the modem hang up, I must be reset this modem. I use modem command like this in C# but I think it does not work sometimes,

AT&F\r + '13'

13 for enter.

Not releated to the actual issue but you can simplfy your paketFiltre method if you switch on the char directly.

// test for packet identifier
            switch (gelen[18])
            {
                case '1':
                    // code for 1
                    break;
                case '2':
                    // code for 2
                    break;
                case '3':
                    // code for 3
                    break;
                // etc..
            }

If you do this you can remove the if (c[18].ToString() == statements.

[Edit] Note the use of single quotes '1' to indicate a char not a string "1" .

Edited 6 Years Ago by nick.crane: added note

When I researched my application problem, I must be check modem status because sometimes my modem hang up in OH status mean that OH lamp is lighting and the telephone line will not be closed, if I close and open the problem everything will be ok but I must be solve modem hang up problem and I must be clear the buffer in every my process. I must be know modem status and If I check the modem hang up, I must be reset this modem. I use modem command like this in C# but I think it does not work sometimes,

AT&F\r + '13'

13 for enter.

It is a long time since I did any work with modems but I think you might need to prefix your command with "+++" to get the modem in to command mode.
Do some googling and check that.

Edited 6 Years Ago by nick.crane: n/a

Hello Nick,

Can you re-write an application it work with system.io.serialport (7 ports with thread) and every process will end and modem will reset these command :

+++ ATZ0 AT&F   ATS0=1   ATM0

Please help me in this situation...

This article has been dead for over six months. Start a new discussion instead.