PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/examples/tcpsrv.asm

http://github.com/ece291/ece291-pmodelib
Assembly | 148 lines | 96 code | 30 blank | 22 comment | 0 complexity | 2897d5b12a641d09a5e587c762997b36 MD5 | raw file
  1. ; A simple TCP server (tcpcli connects to this). Runs until a key is pressed
  2. ; By Peter Johnson, 2001
  3. ;
  4. ; $Id: tcpsrv.asm,v 1.1 2001/04/10 09:08:53 pete Exp $
  5. %include "lib291.inc"
  6. BITS 32
  7. GLOBAL _main
  8. SECTION .data
  9. _port dw 12345 ; port number (host order)
  10. SECTION .bss
  11. _socket resd 1 ; listening socket
  12. _connsocket resd 1 ; connection socket
  13. _gotaccept resb 1
  14. _address resb SOCKADDR_size ; SOCKADDR structure
  15. buf_len equ 16*1024
  16. _buf resb buf_len
  17. SECTION .text
  18. _main:
  19. call _LibInit
  20. ; Initialize the socket library
  21. call _InitSocket
  22. test eax, eax
  23. jnz near .done
  24. ; Create a socket
  25. invoke _Socket_create, dword SOCK_STREAM
  26. test eax, eax
  27. js near .exit
  28. mov [_socket], eax
  29. ; Set up address structure:
  30. ; First the port
  31. invoke _Socket_htons, word [_port]
  32. mov [_address+SOCKADDR.Port], ax
  33. ; Then the address - INADDR_ANY means any address (don't care)
  34. mov dword [_address+SOCKADDR.Address], INADDR_ANY
  35. ; Bind socket to that address and port
  36. invoke _Socket_bind, dword [_socket], dword _address
  37. test eax, eax
  38. jnz near .close
  39. ; Install a callback for incoming connections on the socket
  40. invoke _LockArea, ds, dword _gotaccept, dword 1
  41. invoke _LockArea, cs, dword _SocketHandler, dword _SocketHandler_end-_SocketHandler
  42. invoke _Socket_SetCallback, dword _SocketHandler
  43. test eax, eax
  44. jnz near .close
  45. invoke _Socket_AddCallback, dword [_socket], dword SOCKEVENT_ACCEPT
  46. test eax, eax
  47. jnz near .close
  48. ; Start accepting connections
  49. invoke _Socket_listen, dword [_socket], dword 5
  50. test eax, eax
  51. jnz near .deinstall
  52. .notdone:
  53. ; loop until keypress (exit) or new connection (process it)
  54. mov ah, 1 ; [BIOS] check for keystroke
  55. int 16h
  56. jnz .quit
  57. cmp byte [_gotaccept], 1
  58. je .gotconn
  59. jmp short .notdone
  60. .gotconn:
  61. ; accept the connection: returns a socket for the connection
  62. ; we don't care about the remote address, so don't get it
  63. ; this blocks (waits for a connection) unless one is waiting for us
  64. invoke _Socket_accept, dword [_socket], dword 0
  65. test eax, eax
  66. js .notdone ; didn't accept successfully?
  67. mov [_connsocket], eax ; save connection socket
  68. ; clear accept ready flag
  69. mov byte [_gotaccept], 0
  70. ; Get bytes until connection closed (no data remaining)
  71. .getmore:
  72. invoke _Socket_recv, dword [_connsocket], dword _buf, dword buf_len-1, dword 0
  73. test eax, eax
  74. js .closeconn ; error on receive
  75. jz .closeconn ; no data left
  76. ; Print out the data
  77. mov ecx, eax
  78. xor ebx, ebx
  79. .printloop:
  80. mov ah, 06h
  81. mov dl, [_buf+ebx]
  82. int 21h
  83. inc ebx
  84. cmp ebx, ecx
  85. jb .printloop
  86. jmp short .getmore
  87. .closeconn:
  88. ; close the connection socket
  89. invoke _Socket_close, dword [_connsocket]
  90. jmp short .notdone
  91. .quit:
  92. ; grab the keypress so it doesn't print out after the program exits
  93. xor eax, eax
  94. int 16h
  95. .deinstall:
  96. invoke _Socket_SetCallback, dword 0
  97. .close:
  98. invoke _Socket_close, dword [_socket]
  99. .exit:
  100. call _ExitSocket
  101. .done:
  102. call _LibExit
  103. ret
  104. proc _SocketHandler
  105. .Socket arg 4
  106. .Event arg 4
  107. ; make sure we're getting an accept on the socket we're interested in!
  108. mov eax, [ebp+.Socket]
  109. cmp eax, [_socket]
  110. jne .done
  111. mov eax, [ebp+.Event]
  112. cmp eax, SOCKEVENT_ACCEPT
  113. jne .done
  114. mov byte [_gotaccept], 1
  115. .done:
  116. ret
  117. endproc
  118. _SocketHandler_end