Введение
После́довательный порт, а также серийный порт или COM-порт — двунаправленный последовательный интерфейс.
Последовательным данный порт называется потому, что информация через него передаётся по одному биту, бит за битом (в отличие от параллельного порта). Хотя некоторые другие интерфейсы компьютера — такие как Ethernet, FireWire и USB — также используют последовательный способ обмена, название «последовательный порт» закрепилось за портом, имеющим стандарт RS-232C.
Особенностью данного порта по сравнению с другими "последовательными" технологиями является факт отсутствия каких-либо временных требований между 2 байтами. Временные требования есть только между битами одного байта (включая старт, стоп и четность), величина, обратная временной паузе между битами одного байта, называется скорость передачи. Также в этой технологии отсутствует понятие "пакет".
Другие "последовательные" технологии, такие, как USB или Ethernet, имеют понятие "пакет", и накладывают жесткие временные требования между всеми битами одного пакета.
Некоторые протоколы связи с индустриальным оборудованием налагают жесткие временные требования между байтами последовательного порта. Такие протоколы крайне сложны в реализации в многозадачных ОС со слабой поддержкой реального времени, такой, как Windows, и потому зачастую требуют MS-DOS и устаревшего ПО почти 20-летней давности на управляющем компьютере.
Назначение
Наиболее часто для последовательного порта персональных компьютеров используется стандарт RS-232C. Ранее последовательный порт использовался для подключения терминала, позже для модема или мыши. Сейчас он используется для соединения с источниками бесперебойного питания, для связи с аппаратными средствами разработки встраиваемых вычислительных систем, спутниковыми ресиверами, кассовыми аппаратами, а также с приборами систем безопасности объектов.
С помощью COM-порта можно соединить два компьютера, используя так называемый «нуль-модемный кабель» (см. ниже). Использовался со времен MS-DOS для перекачки файлов с одного компьютера на другой, в UNIX для терминального доступа к другой машине, а в Windows (даже современной) - для отладчика уровня ядра.
Достоинством технологии является крайняя простота оборудования. Недостатком является низкая скорость, крупные размеры разъемов, а также зачастую высокие требования к времени отклика ОС и драйвера и высокое количество прерываний (одно на половину аппаратной очереди, т.е. 8 байт).
Актуальность Широко распространённый в IBM PC-совместимых компьютерах, последовательный порт в настоящее время морально устарел (Спецификация PC99 — один из примеров попытки избавиться в современных материнских платах от наследия старых интерфейсов), но ещё нередко присутствует на современных компьютерах и используется в промышленном и узкоспециальном оборудовании. В настоящее время в IBM PC-совместимых компьютерах активно вытесняется интерфейсом USB, в Macintosh — USB и FireWire.
Существуют стандарты на эмуляцию последовательного порта над USB и над Bluetooth (эта технология в значительной степени и проектировалась как «беспроводной последовательный порт»).
Тем не менее программная эмуляция данного порта широко используется и сегодня. Так, например, практически все мобильные телефоны эмулируют внутри себя классический COM-порт и модем для реализации тетринга — доступа компьютера в Интернет через GPRS/EGDE/3G оборудование телефона. При этом для физического подключения к компьютеру используется USB, Bluetooth или Wi-Fi.
Описание программы
В рамках курсового проекта разработал приложение, предоставляющее возможность общения пользователей между собой находясь за разными компьютерами, соединёнными нуль-модемным кабелем по COM порту. Не имея технической возможности тестирования приложения на подключенных между собой компьютерах, принял решение использовать программный эмулятор COM портов, а именно com0com для 32 битной ОС Windows и Virtual Serial Port Driver 7.1 для 64 битной соответственно.
Элементы управления приложения:
1 – выбор ком порта; 2 – задается ник; 3 – история сообщений; 4 – элемент для ввода сообщения; 5 – отправка сообщения;
Рисунок 1 – Элементы управления
Ниже приведен скриншот работающего приложения:
Рисунок 2 – Работающее приложение
Исходный текст программы
namespace ComChat
{
public partial class Form1: Form
{
public const String NICK_MESSAGE = "{NICK}";
public const String TEXT_MESSAGE = "{TEXT}";
static public String nick;
static public String apponentNick;
static Font textFont;
static Font infoFont;
static Font nickFont;
static SerialPort serialPort;
public Form1()
{
serialPort = new SerialPort();
textFont = new Font("Times New Roman",12, FontStyle.Regular);
infoFont = new Font("Times New Roman", 12, FontStyle.Italic);
nickFont = new Font("Times New Roman", 12, FontStyle.Bold);
InitializeComponent();
Initialize();
}
private void Form1_Load(object sender, EventArgs e)
{
foreach (string s in SerialPort.GetPortNames())
comPortCB.Items.Add(s);
if (comPortCB.Items.Count==0)
MessageBox.Show("Не найдено ни одного COM порта");
}
private void button1_Click(object sender, EventArgs e)
{
Boolean flag = false;
if (!serialPort.IsOpen)
{
writeToChat("Не выбран COM порт\n", Color.Brown, infoFont);
flag = true;
}
if (nickTextBox.Text == "")
{
writeToChat("Введите ник!\n", Color.Brown, infoFont);
flag = true;
}
if (flag) return;
if (nick!= nickTextBox.Text)
serialPort.WriteLine(NICK_MESSAGE + nickTextBox.Text);
writeToChat("<me>: ", Color.Red, nickFont);
writeToChat(inputTextBox.Text + '\n');
serialPort.WriteLine(TEXT_MESSAGE + inputTextBox.Text);
inputTextBox.Text = "";
}
void writeToChat(String str, Color color, Font font)
{
this.Invoke((MethodInvoker)delegate()
{
this.chatTextBox.SelectionFont = font;
this.chatTextBox.SelectionColor = color;
this.chatTextBox.AppendText(str);
});
}
void writeToChat(String str)
{
this.Invoke((MethodInvoker)delegate()
{
this.chatTextBox.SelectionFont = textFont;
this.chatTextBox.SelectionColor = Color.Black;
this.chatTextBox.AppendText(str);
});
}
void Initialize()
{
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
serialPort.ReadTimeout = 500;
serialPort.WriteTimeout = 500;
serialPort.DtrEnable = true;
serialPort.Encoding = Encoding.GetEncoding(1251);
}
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
string income = serialPort.ReadLine();
string type = income.Substring(0, 6);
income = income.Remove(0, 6);
switch (type)
{
case NICK_MESSAGE:
apponentNick = income;
break;
case TEXT_MESSAGE:
writeToChat(String.Format("<{0}>: ", apponentNick), Color.Blue, nickFont);
writeToChat(income + '\n');
break;
}
}
catch (TimeoutException) { }
}
private void comPortCB_SelectionChangeCommitted(object sender, EventArgs e)
{
if (serialPort.IsOpen) serialPort.Close();
serialPort.PortName = (String)comPortCB.SelectedItem;
serialPort.Open();
}
}
}