Вступление В этой статье я расскажу, как использовать WinSock Control. Компонент WinSock позволяет работать с протоколами TCP и UDP, используя архитектуру клиент-сервер: устанавливать соединение, передавать и принимать данные. В данной части статьи речь пойдет об использовании WinSock’а с протоколом TCP. Основные понятия Перед тем, как данные будут переданы, должно быть установлено соединение между клиентом и сервером. Компонент WinSock не виден во время работы программы, в точности как элемент Timer. Сервер - программа, которая прослушивает определенный порт, принимает и обрабатывает входящие запросы на соединение и обменивается данными с клиентом. Клиент - это программа, которая отправляет серверу запрос на соединение и, если оно успешно установлено, взаимодействует с сервером. Для установки соединения клиенту требуется IP адрес сервера и порт. Невозможна установка более одного соединения через один компонент WinSock. Исключение - массив контролов (подробнее об этом во второй части статьи). Установка протокола Для того чтобы установить TCP протокол, используй свойство «винсока» Protocol: Winsock1.Protocol = sckTCPProtocol Использование UDP протокола в данной статье я рассматривать не буду. Как это работает - TCP сервер начинает прослушивать определенный порт
- TCP клиент устанавливает соединение с сервером
- Происходит обмен данными
- Связь прерывается
Как узнать IP адрес своего сервера
Если ты тестируешь программу у себя на компьютере – можешь использовать IP адрес 127.0.0.1. Это локальный адрес, по которому всегда можно соединиться с сервером на своем компьютере. Как правило, настоящий IP адрес сервера можно узнать из свойства LocalIP (например, Winsock1.LocalIP). Обрати внимание! Если твой компьютер подключен к Интернету через шлюз, то, в большинстве случаев, установить соединение с твоим сервером можно будет только локально или из сети LAN. При Dialup соединении твой IP адрес будет меняться при каждой установке соединения с провайдером. Свойства компонента | Свойство | Описание | Возможные значения | | Protocol | Устанавливает протокол: TCP или UDP | sckTCPProtocol sckUDPProtocol | | State | Текущее состояние соединения | sckClosed sckClosing sckConnected sckConnecting sckConnectionPending sckError sckHostResolved sckListening sckOpen sckResolvingHost | | RemoteHost | Удаленный IP адрес или DNS имя сервера | Любая строка, например: www.vbcoding.org.ua | | LocalIP | Содержит IP-адрес компьютера, на котором работает программа | Любая строка, например: 127.0.0.1 | | RemotePort | Удаленный порт, на котором работает сервер | Любое число от 0 до 65535, например 80 | | LocalPort | Локальный порт, обычно используется на сервере для задания порта, который будет прослушиваться на запросы соединений. | Любое число от 0 до 65535, например 80 | Методы компонента | Метод | Описание | | Accept(requestID As Long) | Используется на сервере для подтверждения входящего запроса установки соединения. Перед вызовом метода следует остановить прослушивание порта requestID – идентификатор запроса на соединение | | Close | Закрывает соединение и останавливает прослушивание порта | | Connect([RemoteHost], [RemotePort]) | Отправляет запрос на соединение RemoteHost – IP адрес удаленного компьютера RemotePort – удаленный порт | | Listen | Начинает прослушивать порт LocalPort на IP адресе LocalIP | | GetData(data, [type], [maxLen]) | Принимает данные, должно быть установлено соединение data – сюда принимаются данные обычно переменная типа String type – Тип переменной, например vbString maxLen – максимальная длина скачиваемых данных в байтах, не всегда правильно работает | | SendData(data) | Отправляет данные data, должно быть установлено соединение | События компонента | Событие | Описание | | ConnectionRequest(requestID As Long) | Происходит при прослушивании порта, когда получен запрос на соединение requestID – идентификатор запроса на соединение для передачи методу Accept в качестве аргумента | | DataArrival(bytesTotal As Long) | Получены данные bytesTotal – количество байтов в принимаемых данных | | Close | Закрывается соединение | | Connect | Установлено соединение | | SendProgress(bytesSent As Long, bytesRemaining As Long) | Отправляются данные bytesSent – количество переданнях даннях в байтах bytesRemaining – осталось передать | | SendComplete | Данные отправлены | | Error(Number As Integer, Description As String, Scode As Long, Source As String, HelpFile As String, HelpContext As Long, CancelDisplay As Boolean) | Ошибка, детали в аргументе Description | Обрати внимание! Если ты отправляешь несколько пакетов за небольшой промежуток времени, они могут слиться в один. Чтобы этого избежать, в начале и конце каждого пакета добавляй служебный набор символов, а при получении данный используй функцию Split для разделения пакетов: Dim s() As String, i As Long, strCurrentData As String s = Split(strData, "этот самый служебный набор символов") ' Перечисление всех пакетов For i = 0 To UBound(s) If Len(Trim(s(i))) > 0 Then 'В пакете должны быть данные strCurrentData = s(i) 'Здесь вставь код обработки каждого пакета данных strCurrentData End If Next Создание простого сервера для чата клиент-сервер - Создаем новый Standard ЕХЕ проект
- Устанавливаем свойство Caption формы “TCP Server”
- В меню проект -> Компоненты устанавливаем галочку на компоненте Microsoft Winsock Control
- Размещаем на форме элемент WinSock1
- Добавляем на форму TextBox’ы txtSendData и txtOutput; устанавливаем для txtOutput свойствам Multiline и ScrollBars соответственно значения True и 2 – Вертикаль; добавляем Command cmdSendData
- Вставляем в форму следующий код:
Private Sub cmdSendData_Click() 'Отправляем данные Winsock1.SendData txtSendData.Text 'Записываем в лог чата txtOutput.Text = txtOutput.Text & vbNewLine & "Сервер: " & txtSendData.Text 'Стираем текст txtSendData.Text = "" 'передаем фокус ввода текстовому полю txtSendData.SetFocus End Sub Private Sub Form_Load() 'Блокируем лог чата от ввода txtOutput.Locked = True 'Устанавливаем размеры элементов txtOutput.Move 0, 0, Me.Width, Me.Height * 0.6 txtSendData.Move 0, txtOutput.Height + 10, Me.Width cmdSendData.Move 0, txtSendData.Top + txtSendData.Height, Me.Width 'Устанавливаем другие свойства txtOutput.Text = "" txtSendData.Text = "Введите сюда текст, чтобы отправить" cmdSendData.Caption = "Отправить" 'Устанавливаем порт для прослушивания Winsock1.LocalPort = 1001 'Начинаем прослушивать Winsock1.Listen End Sub Private Sub txtSendData_KeyPress(KeyAscii As Integer) 'Если нажат Enter - отправляем данные If KeyAscii = 13 Then cmdSendData_Click End Sub Private Sub Winsock1_Close() 'Закрываем соединение, если оно еще не закрыто If Winsock1.State <> sckClosed Then Winsock1.Close 'Начинаем прослушивать еще раз Winsock1.Listen End Sub Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long) 'Останавливаем прослушивание '(Обязательно!) Winsock1.Close 'Подключаем клиента Winsock1.Accept requestID 'Очищаем лог разговора txtOutput.Text = "" End Sub Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim s$ 'Принимаем все данные Winsock1.GetData s, vbString 'Записываем данные в лог разговора txtOutput.Text = txtOutput.Text & vbNewLine & "Клиент: " & s 'Перемещаем курсор в конец лога txtOutput.SelStart = txtOutput.SelLength End Sub Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) MsgBox Description, vbCritical Winsock1_Close End Sub Создание простого клиента для чата клиент-сервер - Создаем новый Standard ЕХЕ проект
- Устанавливаем свойство Caption формы “TCP Client”
- В меню проект -> Компоненты устанавливаем галочку на компоненте Microsoft Winsock Control
- Размещаем на форме элемент WinSock1
- Добавляем на форму TextBox’ы txtSendData и txtOutput; устанавливаем для txtOutput свойствам Multiline и ScrollBars соответственно значения True и 2 – Вертикаль; добавляем Command cmdSendData
- Вставляем в форму следующий код:
Private Sub cmdSendData_Click() 'Отправляем данные Winsock1.SendData txtSendData.Text 'Записываем в лог чата txtOutput.Text = txtOutput.Text & vbNewLine & "Клиент: " & txtSendData.Text 'Стираем текст txtSendData.Text = "" 'передаем фокус ввода текстовому полю txtSendData.SetFocus End Sub Private Sub Form_Load() 'Блокируем лог чата от ввода txtOutput.Locked = True
'Устанавливаем размеры элементов txtOutput.Move 0, 0, Me.Width, Me.Height * 0.6 txtSendData.Move 0, txtOutput.Height + 10, Me.Width cmdSendData.Move 0, txtSendData.Top + txtSendData.Height, Me.Width 'Устанавливаем другие свойства txtOutput.Text = "" txtSendData.Text = "Введите сюда текст, чтобы отправить" cmdSendData.Caption = "Отправить"
'Устанавливаем соединение Winsock1.Connect "127.0.0.1", 1001 End Sub Private Sub txtSendData_KeyPress(KeyAscii As Integer) 'Если нажат Enter - отправляем данные If KeyAscii = 13 Then cmdSendData_Click End Sub Private Sub Winsock1_Close() 'При закрыытии соединенич останавливаем выполнение программы Unload Me End Sub Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long) Dim s$ 'Принимаем все данные Winsock1.GetData s, vbString 'Записываем данные в лог разговора txtOutput.Text = txtOutput.Text & vbNewLine & "Сервер: " & s 'Перемещаем курсор в конец лога txtOutput.SelStart = txtOutput.SelLength End Sub Private Sub Winsock1_Error(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean) MsgBox Description, vbCritical Winsock1_Close End Sub Исходник того, что у меня получилось, ты можешь скачать здесь . Тестирование простого чата клиент-сервер - Запускаем сервер
- Запускаем клиент
- Вводим текстовые данные в txtSendData окна сервера и нажимаем «Отправить»; данные должны быть переданы в окно клиента
- Вводим текстовые данные в txtSendData окна клиента и нажимаем «Отправить»; данные должны быть переданы в окно сервера
Вот вроде и конец первой части. Автор Таранов Влад(
Этот e-mail адрес защищен от спам-ботов, для его просмотра у Вас должен быть включен Javascript
). Отправляйте свои вопросы мне на E-Mail. Данная статья может быть опубликована или процитирована на Интернет-ресурсах с обязательным условием сохранения ссылки на источник – http://www.vbcoding.org.ua . Желаю тебе успехов в освоении премудростей программирования.
|