You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
Can you show me how you did "a single socket with overlapped I/O." I would like to give overlapped i/o a try. Thanks!
Sorry for the delay. I just spotted your post. I attached a couple of files that may help you out. The first is a console app that I was using to test multiple threads handling messages from a single socket (or course, it can also be a single socket). It uses overlapped I/O for the threads so may be useful. It is by no means a polished app, but it does work. Essentially, it looks for received UDP packets and responds by sending responses to the sender. The second app is a GUI for sending UDP messages to the first app. I'm not really a GUI person so it's also not elegant. I used PB Forms to assemble the interface.
Jerry's code is very fast so it didn't give dialog time to refresh.
I changed default from sending 1 message to 1000 messages and receiving responses.
Also refreshes control every 100-messages so you see something.
SendTestMessage2.bas
Code:
#PBFORMS CREATED V2.01
#COMPILE EXE
#DIM ALL
#PBFORMS BEGIN INCLUDES
#RESOURCE "SendTestMessage.pbr"
%USEMACROS = 1
#INCLUDE ONCE "WIN32API.INC"
#INCLUDE ONCE "COMMCTRL.INC"
#INCLUDE ONCE "PBForms.INC"
#PBFORMS END INCLUDES
#PBFORMS BEGIN CONSTANTS
%BTN_Send = 1010
%CHK_waitRecv = 1015
%FRM_Main = 101
%IDC_IPAddress = 1009
%LBL_LABEL1 = 1004
%LBL_LABEL2 = 1005
%LBL_LABEL3 = 1006
%LBL_LABEL4 = 1008
%LBL_LABEL5 = 1012
%LBL_LABEL6 = 1014
%TXT_Count = 1007
%TXT_FarPort = 1011
%TXT_Message = 1003
%TXT_Port = 1002
%TXT_Status = 1013
#PBFORMS END CONSTANTS
'--------------------------------------------------------------------------------------------------
DECLARE CALLBACK FUNCTION ShowMainProc()
DECLARE FUNCTION ShowMain(BYVAL hParent AS DWORD) AS LONG
#PBFORMS DECLARATIONS
' ** Main Application Entry Point **
'--------------------------------------------------------------------------------------------------
FUNCTION PBMAIN()
PBFormsInitComCtls (%ICC_WIN95_CLASSES OR %ICC_DATE_CLASSES OR %ICC_INTERNET_CLASSES)
ShowMain %HWND_DESKTOP
END FUNCTION
'--------------------------------------------------------------------------------------------------
GLOBAL ghDlg AS DWORD
FUNCTION zIP2String ALIAS "zip2string" (BYVAL lAddr AS DWORD) EXPORT AS STRING
LOCAL pAddr AS BYTE PTR
pAddr=VARPTR(lAddr)
FUNCTION = USING$("#_.#_.#_.#", @pAddr, @pAddr[1], @pAddr[2], @pAddr[3])
END FUNCTION
FUNCTION zString2IP ALIAS "zstring2ip" (BYREF sIPAddr AS STRING) EXPORT AS LONG
REGISTER n AS LONG
LOCAL sWork AS STRING '
LOCAL sTemp AS STRING
sIPAddr = REMOVE$(sIPAddr, ANY CHR$(0,32)) ' Make sure there's no spaces or nulls
sWork = SPACE$(4) ' Build a buffer for calculations
IF TALLY(sIPAddr,".") <> 3 THEN ' Make sure we have exactly 3 periods
EXIT FUNCTION
ELSE
FOR n = 1 TO 4 ' Process four values for IPv4
sTemp = PARSE$(sIPAddr, ".", n) ' Pointer value adjusted by ParseString
'---- Make sure data element is in range (num 0 to 255)
IF LEN(sTemp) > 3 OR sTemp="" OR VERIFY(1, sTemp, "0123456789") OR VAL(sTemp) > 255 THEN
EXIT FUNCTION ' Some problem with input string so get out
ELSE
ASC(sWork,n) = VAL(sTemp) ' Looks OK. Update output string.
END IF
NEXT n
END IF
FUNCTION = CVL(sWork) ' Move data to return value.
END FUNCTION ' zString2IP
FUNCTION SendUdpMessage( _
BYVAL locPort AS LONG, _
BYVAL farAddr AS LONG, _
BYVAL farport AS LONG, _
BYVAL cnt AS LONG, _
BYREF sMsg AS STRING _
) AS LONG
REGISTER n AS LONG
STATIC hSock AS LONG
LOCAL sBuff AS STRING
LOCAL rxPort AS LONG
LOCAL rxAddr AS LONG
LOCAL wait AS LONG
CONTROL SET TEXT ghDlg, %txt_status, ""
CONTROL DISABLE ghDlg, %BTN_Send
CONTROL SET TEXT ghDlg, %BTN_Send, "Wait"
' IF hSock = 0 THEN
hSock = FREEFILE
UDP OPEN PORT locPort AS hSock TIMEOUT 100
IF ERR THEN
' MSGBOX "Error starting UDP socket
BEEP
CONTROL SET TEXT ghDlg, %txt_status, "Error starting UDP socket =" & STR$(ERR)
EXIT FUNCTION
END IF
' END IF
FOR n = 1 TO cnt
UDP SEND hSock, AT farAddr, farPort, sMsg
IF ERR THEN
'IF cnt = n THEN 'change from 1
CONTROL SET TEXT ghDlg, %txt_status, "Error ssending message =" & STR$(ERR)
MSGBOX "Error sending message =" & STR$(ERR)
EXIT FUNCTION
'END IF
END IF
CONTROL GET CHECK ghDlg, %CHK_waitRecv TO wait
IF wait THEN
UDP RECV hSock, FROM rxAddr, rxPort, sBuff
IF ERR THEN
IF cnt = 1 THEN
CONTROL SET TEXT ghDlg, %txt_status, "Error receiving message =" & STR$(ERR)
MSGBOX "Error receiving message =" & STR$(ERR)
END IF
ELSE
'IF cnt = n THEN
CONTROL SET TEXT ghDlg, %txt_status, "Resp" + STR$(n)+ " from " & _
$CRLF & zIp2String(rxAddr) & ":" & FORMAT$(rxPort)
IF n MOD 100 = 0 THEN CONTROL REDRAW ghDlg,%txt_status:SLEEP 10
' MSGBOX "Received response message from " & zIp2String(rxAddr) & ":" & FORMAT$(rxPort)
'END IF
END IF
END IF
NEXT n
CONTROL SET TEXT ghDlg, %BTN_Send, "Send"
CONTROL ENABLE ghDlg, %BTN_Send
'-- Wait for a bit and close the port. This gives the dest host a chance to send a response
' without getting a DestHostUnreachable error because we already shut down. 100ms should
' be long enough.
SLEEP 100
UDP CLOSE hSock
DIALOG REDRAW ghDlg
END FUNCTION
'--------------------------------------------------------------------------------------------------
' ** CallBacks **
'--------------------------------------------------------------------------------------------------
CALLBACK FUNCTION ShowMainProc()
LOCAL farPort AS DWORD
LOCAL locPort AS DWORD
LOCAL msgCnt AS LONG
LOCAL farAddr AS LONG
LOCAL sMsg AS STRING
' LOCAL hSock AS LONG
LOCAL sTemp AS STRING
SELECT CASE AS LONG CB.MSG
CASE %WM_INITDIALOG
' Initialization handler
CASE %WM_NCACTIVATE
STATIC hWndSaveFocus AS DWORD
IF ISFALSE CB.WPARAM THEN
' Save control focus
hWndSaveFocus = GetFocus()
ELSEIF hWndSaveFocus THEN
' Restore control focus
SetFocus(hWndSaveFocus)
hWndSaveFocus = 0
END IF
CASE %WM_COMMAND
' Process control notifications
SELECT CASE AS LONG CB.CTL
IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
'-- Test the local port value.
CONTROL SET TEXT CB.HNDL,%txt_status,"Sending ...":DIALOG REDRAW CB.HNDL
CONTROL GET TEXT CB.HNDL, %txt_port TO sTemp
locPort = VAL(sTemp)
IF (locPort = 0) OR (locPort > 65535) THEN
' MSGBOX "Local port value is out of range.", %MB_ICONWARNING OR %MB_TASKMODAL, "Port Validation"
BEEP
CONTROL SET TEXT ghDlg, %txt_status, "Invalid local port!"
EXIT FUNCTION
END IF
'-- Test the far port value.
CONTROL GET TEXT CB.HNDL, %txt_farport TO sTemp
farPort = VAL(sTemp)
IF (farPort = 0) OR (farPort > 65535) THEN
MSGBOX "Local port value is out of range.", %MB_ICONWARNING OR %MB_TASKMODAL, "Port Validation"
EXIT FUNCTION
END IF
'-- Test IP address.
CONTROL GET TEXT CB.HNDL, %idc_ipaddress TO sTemp
farAddr = zString2IP(sTemp)
'-- Get the message count.
CONTROL GET TEXT CB.HNDL, %txt_Count TO sTemp
msgCnt = VAL(sTemp)
' MSGBOX "%BTN_Send=" + FORMAT$(farAddr), %MB_TASKMODAL
' MSGBOX STR$(farPort), %MB_ICONWARNING, "Port Validation"
CONTROL GET TEXT CB.HNDL, %txt_message TO sTemp
SendUDPMessage locPort, farAddr, farPort, msgCnt, sTemp
END IF
END SELECT
END SELECT
END FUNCTION
' ** Dialogs **
'--------------------------------------------------------------------------------------------------
FUNCTION ShowMain(BYVAL hParent AS DWORD) AS LONG
LOCAL lRslt AS LONG
#PBFORMS BEGIN DIALOG %FRM_Main->->
LOCAL hDlg AS DWORD
DIALOG NEW hParent, "Send Message", 237, 168, 163, 162, %WS_POPUP OR _
%WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
%WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_CENTER OR _
%DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR _
%WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO hDlg
CONTROL ADD TEXTBOX, hDlg, %TXT_Port, "9999", 40, 25, 30, 15, %WS_CHILD OR _
%WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_AUTOHSCROLL OR %ES_NUMBER, _
%WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
%WS_EX_RIGHTSCROLLBAR
CONTROL ADD TEXTBOX, hDlg, %TXT_Message, "My Message", 40, 45, 115, 25
CONTROL ADD LABEL, hDlg, %LBL_LABEL1, "Far Addr", 0, 5, 35, 15, _
%WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD LABEL, hDlg, %LBL_LABEL2, "Loc Port", 0, 25, 30, 15, _
%WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD LABEL, hDlg, %LBL_LABEL3, "Tx Msg", 5, 45, 30, 15, %WS_CHILD _
OR %WS_VISIBLE OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD TEXTBOX, hDlg, %TXT_Count, "1000", 40, 115, 40, 15, %WS_CHILD OR _
%WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_AUTOHSCROLL OR %ES_NUMBER, _
%WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
%WS_EX_RIGHTSCROLLBAR
CONTROL ADD LABEL, hDlg, %LBL_LABEL4, "Msg Cnt", 5, 115, 30, 15, _
%WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD "SysIPAddress32", hDlg, %IDC_IPAddress, "192.168.0.106", 40, 5, _
100, 15, %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP, %WS_EX_CLIENTEDGE OR _
%WS_EX_LEFT OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
CONTROL ADD BUTTON, hDlg, %BTN_Send, "Send", 105, 135, 50, 20
CONTROL ADD TEXTBOX, hDlg, %TXT_FarPort, "9998", 125, 25, 30, 15, _
%WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %ES_LEFT OR %ES_AUTOHSCROLL _
OR %ES_NUMBER, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
%WS_EX_RIGHTSCROLLBAR
CONTROL ADD LABEL, hDlg, %LBL_LABEL5, "Far Port", 85, 25, 35, 15, _
%WS_CHILD OR %WS_VISIBLE OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD TEXTBOX, hDlg, %TXT_Status, "", 40, 75, 115, 30
CONTROL ADD LABEL, hDlg, %LBL_LABEL6, "Status", 5, 75, 30, 15, %WS_CHILD _
OR %WS_VISIBLE OR %SS_RIGHT OR %SS_CENTERIMAGE, %WS_EX_LEFT OR _
%WS_EX_LTRREADING
CONTROL ADD CHECKBOX, hDlg, %CHK_waitRecv, "Wait For Recv", 95, 115, 60, 15
#PBFORMS END DIALOG
CONTROL SET CHECK hDlg, %CHK_waitRecv,1 'set checkbox to recv messages back
'-- Local address is always the default host address.
LOCAL farAddr AS LONG
HOST ADDR TO farAddr
CONTROL SET TEXT hDlg, %idc_ipaddress, zIp2String(farAddr) 'sTemp
ghDlg = hDlg
DIALOG SHOW MODAL hDlg, CALL ShowMainProc TO lRslt
#PBFORMS BEGIN CLEANUP %FRM_Main
#PBFORMS END CLEANUP
FUNCTION = lRslt
END FUNCTION
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment