Restored from previous forum. Originally posted by ricardo.
Im trying to send/receive some files using some threads.
After a small battle betewn mi PC and i, im making some advance, but im in one point that i can understand what is failing... its 3:30 a.m. maybe my brain dosent work anymore.
Please take a look and see if you can see what im doing wrong.
There are 2 procedures, one for every app (one for the client and one for the server) and both are working now on the same PC, that why both are calling to the same files.
This procedure runs everytime i click a button and its suppoused to send some file (a1.mp3, a2.mp3, a3.mp3, etc) to the server, i want to receive several files at the same time.
The index are the port of the server, cause every thread procedure on the server side has a different port (maybe there some oher way to do it)
Procedure EnviaFile(index.l)
Cont.l = Cont + 1 ; global
Buffer = AllocateMemory(Cont, FileSize("a" + str(cont) + .mp3"), 0)
OpenFile(Cont,"a"+ Str(Cont)+".mp3")
ReadData(Buffer,FileSize("a"+ Str(Cont)+".mp3"))
CloseFile(Cont)
ConnectionID = OpenNetworkConnection("127.0.0.1", (index))
If ConnectionID
SendNetworkData(ConnectionID, Buffer, FileSize("a"+ Str(Cont)+".mp3"))
CloseNetworkConnection(ConnectionID)
;FreeMemory(Cont)
EndIf
EndProcedure
;SERVER SIDE PROCEDURE
This one receives a1.mp3 and writes b1.mp3, etc.
Procedure RecibeFile(Index.l)
Result = CreateNetworkServer(Index)
Cont.l = cont + 1 ;global
Repeat
ServerEvent.l = NetworkServerEvent()
If ServerEvent
Select ServerEvent
Case 2
ClientID = NetworkClientID()
If FindString(IDClient,"*" + Str(cont) + "*",0) = 0; dirty
IDClient = IDClient + "*" + Str(cont) + "* "
Buffer = AllocateMemory(Cont, FileSize("a"+ Str(Cont)+".mp3"), 0)
ReceiveNetworkData(ClientID, Buffer, FileSize("a"+ Str(Cont)+".mp3"))
OpenFile(Cont,"b"+ Str(Cont)+".mp3")
WriteData(Buffer,FileSize("a"+ Str(Cont)+".mp3"))
CloseFile(Cont)
CloseNetworkConnection(Result)
;FreeMemory(Cont)
Conectado.l = 1
EndIf
Case 4
CloseNetworkConnection(Result)
Conectado.l = 1
EndSelect
EndIf
Until Conectado = 1
EndIf
EndProcedure
The result i that i can send/receive apparentely 3 or more files, but writes always the same one.
I make the DIRTY trick because the ServerEvent is received on every thread no matter if its originated on the server connected to another thread and since im using only one client the ClientID is the same too, then i make this dirty trik to know if the event comes from one thread different from this one.
When the server receives some text message, it run s the procedure with a new thread and replay to the client the number of the port recently opened and the waits until getting the file.
And seems to work, create a file with the correct size, but the content of the file is wrong.
The idea is to receive at the same time several files from one or more clients to the same server... but it dosent works ¿any help?
need help on server threads...
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by fweil.
I am trying to explain what I understand from your code first :
- Enviafile is the client side sending a file
- RecibeFile is the server receiving files from clients
If you are running each in separate executable programs, even if running on a single PC at this time, you have the Cont.l variable used for file names indexation, which is a global inside each running program (client and server).
So names are probably correctly handled, but you should use a FileName variable for code clarity.
Then in the server side procedure, you set a buffer with a length of the next file to be received (allocatememory before receivenetworkdata). I suppose this is a first issue because you don't know the size of the file to be received at that time. Also you declare the allocatememory to a Buffer variable instead of a *Buffer pointer which, if I do not mistake is a bug.
I am not sure to have seen all and just reply you reading your post, not testing the code on my machine, but I hope this will help to start in solving issues going further in the way you want.
Rgrds
Francois Weil
14, rue Douer
F64100 Bayonne
I am trying to explain what I understand from your code first :
- Enviafile is the client side sending a file
- RecibeFile is the server receiving files from clients
If you are running each in separate executable programs, even if running on a single PC at this time, you have the Cont.l variable used for file names indexation, which is a global inside each running program (client and server).
So names are probably correctly handled, but you should use a FileName variable for code clarity.
Then in the server side procedure, you set a buffer with a length of the next file to be received (allocatememory before receivenetworkdata). I suppose this is a first issue because you don't know the size of the file to be received at that time. Also you declare the allocatememory to a Buffer variable instead of a *Buffer pointer which, if I do not mistake is a bug.
I am not sure to have seen all and just reply you reading your post, not testing the code on my machine, but I hope this will help to start in solving issues going further in the way you want.
Rgrds
Francois Weil
14, rue Douer
F64100 Bayonne
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Pupil.
I see that you try to send, on the client side, to the server on different ports? Do you have a multiport server, or are your server listening to one specific port, from what i've seen when trying out the network capabillities of PB it's only possible for the server to listen to ONE port at a time(anyone, correct me if i'm wrong). You can use the OpenNetworkConnection() command serveral times after oneother(with same IP and port) and you'll get a different ConnectionID each time, that is if you don't close a connection between the calls.
On the server side you have to differentiate the clients by using the NetworkClientID() command, having this information you can see which client connection triggered the NetworkServerEvent() and easily direct the input to the file associated with that particular connectionID.
Well, just some small thoughts on my side..
I see that you try to send, on the client side, to the server on different ports? Do you have a multiport server, or are your server listening to one specific port, from what i've seen when trying out the network capabillities of PB it's only possible for the server to listen to ONE port at a time(anyone, correct me if i'm wrong). You can use the OpenNetworkConnection() command serveral times after oneother(with same IP and port) and you'll get a different ConnectionID each time, that is if you don't close a connection between the calls.
On the server side you have to differentiate the clients by using the NetworkClientID() command, having this information you can see which client connection triggered the NetworkServerEvent() and easily direct the input to the file associated with that particular connectionID.
Well, just some small thoughts on my side..
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by ricardo.
I open a new port for every file...I see that you try to send, on the client side, to the server on different ports? Do you have a multiport server, or are your server listening to one specific port
Mmmm... i have been able to open multiple ports, but the serverevent is shared betwen all of course.from what i've seen when trying out the network capabillities of PB it's only possible for the server to listen to ONE port at a time(anyone, correct me if i'm wrong).
But using the same port did i will get different results that using new ports?You can use the OpenNetworkConnection() command serveral times after oneother(with same IP and port) and you'll get a different ConnectionID each time, that is if you don't close a connection between the calls.
Since in my example, all the connectio are opened by the same client, the ClientID are the same, no matter if its a new connection in another port. : )On the server side you have to differentiate the clients by using the NetworkClientID() command, having this information you can see which client connection triggered the NetworkServerEvent() and easily direct the input to the file associated with that particular connectionID.
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Pupil.
And here comes the client:
First start the server and then start the client for proper results...
How do you go about it if you want to close one server port?? It's a no-can-do in purebasic at this stage, so probably you're only supposed to run one server on one port in an application (that's my interpretation atleast).Mmmm... i have been able to open multiple ports, but the serverevent is shared betwen all of course.
It's isn't that easy, one client can open multiple connections at the same time to a server and on the server side each of these connections get a different ID. You can test this with my example below:Since in my example, all the connectio are opened by the same client, the ClientID are the same, no matter if its a new connection in another port. : )
Code: Select all
; server
If OpenWindow(0,0,0,200,100, #PB_Window_SystemMenu, "server") = 0
End
EndIf
If InitNetwork() = 0
End
EndIf
If CreateGadgetList(WindowID())
ListViewGadget(0, 5, 10, 190, 80)
Else
End
EndIf
If CreateNetworkServer(444) = 0
End
EndIf
Repeat
wevent.l = WindowEvent()
sevent.l = NetworkServerEvent()
If sevent
Select sevent
Case 1 ; New client connected
AddGadgetItem(0, -1, "new ClientID: $"+Hex(NetworkClientID()))
EndSelect
Else
Delay(1)
EndIf
Until wevent = #PB_Event_CloseWindow
Code: Select all
; client
If OpenWindow(0,0,0,200,100, #PB_Window_SystemMenu, "client") = 0
End
EndIf
If InitNetwork() = 0
End
EndIf
If CreateGadgetList(WindowID())
ListViewGadget(0, 5, 10, 190, 80)
Else
End
EndIf
AddGadgetItem(0, -1, "new ConnectionID: $"+Hex(OpenNetworkConnection("127.0.0.1", 444)))
AddGadgetItem(0, -1, "new ConnectionID: $"+Hex(OpenNetworkConnection("127.0.0.1", 444)))
AddGadgetItem(0, -1, "new ConnectionID: $"+Hex(OpenNetworkConnection("127.0.0.1", 444)))
Repeat
wevent.l = WaitWindowEvent()
Until wevent = #PB_Event_CloseWindow
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by ricardo.
I will try your example.
One question:
Under your idea... ¿how could i acomplish multithreading to send/receive files at the same time?
If you open different ports as i do in my example, just close the ConnectionID of this port (i think).How do you go about it if you want to close one server port?? It's a no-can-do in purebasic at this stage, so probably you're only supposed to run one server on one port in an application (that's my interpretation atleast).
I will try your example.
One question:
Under your idea... ¿how could i acomplish multithreading to send/receive files at the same time?
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Pupil.
I haven't tested it, but hopefully you'll be able to see my line of thought...
You create a structure that holds the necessary data, on the server side it can look something like this:One question:
Under your idea... ¿how could i acomplish multithreading to send/receive files at the same time?
Code: Select all
Structure ConnectionType
ID.l
In.b[2048]
InLength.l
Busy.w
FileName.s
EndStructure
Declare ReceiveData(*ptr.ConnectionType)
NewList Clients.ConnectionType()
; some initializations and stuff...
Repeat
WinEvent.l = WindowEvent()
NetEvent.l = NetworkServerEvent()
If NetEvent
Select NetEvent
Case 1 ; Client connected
Case 4 ; Client disconnected
ClientID.l = NetworkClientID()
ResetList(Clients())
While NextElement(Clients())
If Clients()\ID = ClientID
DeleteElement(Clients())
EndIf
Wend
Default ; data has been received
ClientID = NetworkClientID()
*ptr.ConnectionType = 0
ResetList(Clients())
While NextElement(Clients())
If Clients()\ID = ClientID
*ptr = Clients()
EndIf
Wend
If *ptr = 0
If AddElement(Clients())
*ptr = Clients()
*ptr\Busy = #FALSE
*ptr\ID = ClientID
CreateThread(@ReceiveData(), *ptr)
EndIf
Else
If *ptr\Busy = 0
CreateThread(@ReceiveData(), *ptr)
EndIf
EndIf
EndSelect
Else
Delay(1)
EndIf
Until WinEvent = #PB_Event_CloseWindow
End
Procedure ReceiveData(*ptr.ConnectionType)
*ptr\Busy = #TRUE
*ptr\InLength = ReceiveNetworkData(*ptr\ID, @*ptr\In[0], 2048)
If *ptr\FileName ""
Else
; Here you want To either invent a filename or
; you might have sent a name with the first packet that
; is sent and from that derive a filename...
; We'll do this for now:
*ptr\FileName = "Receivedfile"+Str(*ptr\ID)+".dat"
EndIf
If OpenFile(*ptr\ID, *ptr\FileName)
FileSeek(Lof())
WriteData(@*ptr\In[0], *ptr\InLength)
CloseFile(*ptr\ID)
EndIf
*ptr\Busy = #FALSE
EndProcedure
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
-
BackupUser
- PureBasic Guru

- Posts: 16777133
- Joined: Tue Apr 22, 2003 7:42 pm
Restored from previous forum. Originally posted by Pupil.

Glad i was able to help. I'll have some waction afk so i won't be able to help anyone for a week or so, perhaps you app is ready when i come backHi, Pupil
Yes, i see the lines of thoughts and then found some way to do it as i needed.
Really Thanks to all !!