Huge Multi-User Chat
Author |
Message |
GhostCobra
|
Posted: Fri Dec 30, 2005 5:38 pm Post subject: Huge Multi-User Chat |
|
|
Got Source?
Server Code:
code: |
put "Chat Server Started on ", Net.LocalAddress
put ""
const minPort := 20000
const maxPort := 65000
proc waitForChar (incomingConnection : int)
loop
if Net.LineAvailable (incomingConnection) then
exit
end if
end loop
end waitForChar
proc acceptIncoming (clientPort : int)
var port : int := 65
var serverAddress : string := Net.LocalAddress
var clientAddress : string := ""
var incomingConnection : int := Net.WaitForConnection (port, serverAddress)
waitForChar (incomingConnection)
get : incomingConnection, clientAddress : *
put "Client: ", clientAddress, " Connecting on port: ", clientPort
put : incomingConnection, clientPort
Net.CloseConnection (incomingConnection)
end acceptIncoming
proc serverChatConnect (clientPort : int, var clientAddr : string, var clientNick : string, var incomingConnection : int)
var serverAddress : string := Net.LocalAddress
incomingConnection := Net.WaitForConnection (clientPort, serverAddress)
waitForChar (incomingConnection)
get : incomingConnection, clientAddr
waitForChar (incomingConnection)
get : incomingConnection, clientNick
end serverChatConnect
var clientAddr : array minPort .. maxPort of string
var clientNick : array minPort .. maxPort of string
var text : string := ""
var incomingConnection : array minPort .. maxPort of int
for i : minPort .. maxPort
incomingConnection (i) := 0
end for
proc relayText (clientPort : int)
for i : minPort .. maxPort
if incomingConnection (i) not= 1 and incomingConnection (i) <= 0 then
else
put : incomingConnection (i), clientNick (clientPort) + " says: " + text
end if
end for
end relayText
proc relayServerMessage (clientPort : int, text : string)
for i : minPort .. maxPort
if incomingConnection (i) not= 1 and incomingConnection (i) <= 0 then
else
put : incomingConnection (i), clientNick (clientPort) + " has " + text
end if
end for
end relayServerMessage
process acceptText (clientPort : int)
var exitText : string := " exited."
var connectedText : string := " connected."
relayServerMessage (clientPort, connectedText)
loop
waitForChar (incomingConnection (clientPort))
get : incomingConnection (clientPort), text : *
if text not= "exit" then
put "Client ", clientAddr (clientPort), " with nickname ", clientNick (clientPort), " on port ", clientPort, " sent: ", text
relayText (clientPort)
elsif text = "exit" then
put "Client ", clientAddr (clientPort), " with nickname ", clientNick (clientPort), " on port ", clientPort, " has exited."
relayServerMessage (clientPort, exitText)
Net.CloseConnection (incomingConnection (clientPort))
incomingConnection (clientPort) := 0
end if
exit when text = "exit"
end loop
clientAddr (clientPort) := ""
end acceptText
var clientPort : array minPort .. maxPort of int
for i : minPort .. maxPort
clientPort (i) := i
clientAddr (i) := ""
end for
loop
for indexPort : minPort .. maxPort
if clientAddr (indexPort) = "" then
acceptIncoming (clientPort (indexPort))
serverChatConnect (clientPort (indexPort), clientAddr (indexPort), clientNick (indexPort), incomingConnection (indexPort))
fork acceptText (clientPort (indexPort))
exit
else
end if
end for
end loop
|
Client Source:
code: |
import GUI
var w1 : int := Window.Open ("graphics:400;350, nobuttonbar")
var outgoingConnection : int
var serverAddress : string
var chatTextSendBox : int
var chatTextBox : int
var EXIT : boolean := false
proc waitForChar (var newClientPort : int)
loop
if Net.LineAvailable (outgoingConnection) then
get : outgoingConnection, newClientPort
exit
end if
end loop
end waitForChar
proc clientConnect (var newClientPort : int)
var clientAddress : string := Net.LocalAddress
var serverPort : int := 65
outgoingConnection := Net.OpenConnection (serverAddress, serverPort)
put : outgoingConnection, clientAddress
waitForChar (newClientPort)
Net.CloseConnection (outgoingConnection)
end clientConnect
proc clientChatConnect (newClientPort : int, nickName : string)
var clientAddress : string := Net.LocalAddress
outgoingConnection := Net.OpenConnection (serverAddress, newClientPort)
put : outgoingConnection, clientAddress
put : outgoingConnection, nickName
end clientChatConnect
proc sendToServer (text : string)
if text = "exit" then
put : outgoingConnection, text
EXIT := true
else
put : outgoingConnection, text
GUI.SetText (chatTextSendBox, "")
end if
end sendToServer
proc sendToServer2
var text : string := GUI.GetText (chatTextSendBox)
if text = "exit" then
put : outgoingConnection, text
EXIT := true
else
put : outgoingConnection, text
GUI.SetText (chatTextSendBox, "")
end if
end sendToServer2
var newClientPort : int := 0
var nickName : string := "Default"
put "Enter the server address: "
get serverAddress
put "Enter your nickname: "
get nickName
process receiveText
var text : string
loop
exit when EXIT = true
if Net.CharAvailable (outgoingConnection) then
get : outgoingConnection, text : *
GUI.AddLine (chatTextBox, text)
GUI.Refresh
end if
end loop
end receiveText
clientConnect (newClientPort)
clientChatConnect (newClientPort, nickName)
var font1 : int := Font.New ("Arial:10")
cls
chatTextSendBox := GUI.CreateTextFieldFull (5, 5, 320, "", sendToServer, 0, font1, 0)
var chatTextSendButton : int := GUI.CreateButton (335, 1, 20, "Send", sendToServer2)
chatTextBox := GUI.CreateTextBox (5, 30, 320, 310)
fork receiveText
loop
exit when GUI.ProcessEvent or EXIT = true
end loop
put : outgoingConnection, "exit"
Net.CloseConnection (outgoingConnection)
delay (250)
Window.Close (w1)
|
Tested and works. This is for example, and mess with minUsers maxUsers values to increase decrease the loads in the server file. Client file is just a tool |
|
|
|
|
|
Sponsor Sponsor
|
|
|
jrblast
|
Posted: Sat Dec 31, 2005 12:57 am Post subject: (No subject) |
|
|
Set up the server so we can chat through you
cool...Isn't there somehitn like this in the help menu for NET.OpenConnection (or w.e. the command is)? |
|
|
|
|
|
cool dude
|
Posted: Sat Dec 31, 2005 4:47 pm Post subject: (No subject) |
|
|
nice although chat programs on turing is not someone would likely use. by the ways my firewall keeps blocking it (lol). |
|
|
|
|
|
GhostCobra
|
Posted: Sat Dec 31, 2005 11:23 pm Post subject: (No subject) |
|
|
Yes, there is a chat program included with turing, but it only supports P2P chat. (Person to Person).
This supports up to and including 45000 users. It uses almost all available ports on the server side.
One thing I was thinking of, daisy chaining servers. Theoretically a central server with multiple NICs, running a few different instances of the program listening on different NICs each, would be able to multiply your ports by the number of IP addresses available. That is unless Turing actually doesn't give a rats ass what IP your using when accepting connections.
If you want to test the program, I'm running it at 24.109.128.68 (stay off my music lol). |
|
|
|
|
|
GhostCobra
|
Posted: Sun Jan 01, 2006 12:21 am Post subject: (No subject) |
|
|
Suppose I should program in some sort of notification system, didn't notice someone connected |
|
|
|
|
|
masterfenix
|
Posted: Sun Jan 01, 2006 1:01 am Post subject: (No subject) |
|
|
that was me!!! |
|
|
|
|
|
[Gandalf]
|
Posted: Sun Jan 01, 2006 1:08 am Post subject: (No subject) |
|
|
For some reason I can't connect anymore, "Net Error. Windows Socket Library Error #10061". If masterfenix is still connected then it may be that it only does accept one connection.
Overall, it's a well made and fully functional program. As I mentioned using it, the next step could be to implement some current messaging protocol into your program, like IRC. Aside from that, maybe a slight aesthetic improvement would be nice .
*edit* Clearly messing around with the process priority is a bad idea. It works now |
|
|
|
|
|
jrblast
|
Posted: Sun Jan 01, 2006 7:09 pm Post subject: (No subject) |
|
|
i got that same error without changing anything maybe i need to forward some ports? well im at my uncles for the next few days, ill mess around with it when i get home |
|
|
|
|
|
Sponsor Sponsor
|
|
|
GhostCobra
|
Posted: Mon Jan 02, 2006 12:50 am Post subject: (No subject) |
|
|
Yeah, I turned it off, it has memory leak problems (as all of Turing does when involving processes). |
|
|
|
|
|
jrblast
|
Posted: Fri Jan 06, 2006 2:33 am Post subject: (No subject) |
|
|
oh...ill try running the server i dont care...as long as i can still play my 300Mhz game (runescape...laugh/taunt and die!!) ip: 70.27.131.21
just gotta forward the ports, might be a min from posting time
EDIT: Running and forwarded...But when i try to connect to myself...it doesnt work...get some error then the client crashes....well, connect to me night...
EDIT2: Nope, can't still play runescape shutting it down. |
|
|
|
|
|
GhostCobra
|
Posted: Fri Jan 13, 2006 4:11 pm Post subject: (No subject) |
|
|
Its "experimental". Meaning, something that can be done, but it's so unreasonably hoggish. |
|
|
|
|
|
Clayton
|
Posted: Sat Jan 14, 2006 9:22 pm Post subject: (No subject) |
|
|
i like it, i showed it to my compsci class and we had a huge chat class, bit sluggish though but awesome still good job |
|
|
|
|
|
GhostCobra
|
Posted: Sun Feb 19, 2006 1:23 am Post subject: (No subject) |
|
|
*UPDATE*
The code has been updated. If it crashes a connection it shall not be dropped . Unless the address is wrong... lol
CLIENT:
code: |
import GUI
var w1 : int := Window.Open ("graphics:400;370, nobuttonbar")
var outgoingConnection : int
var serverAddress : string
var chatTextSendBox : int
var chatTextBox : int
var EXIT : boolean := false
var nickName : string := "Default"
proc waitForChar (var newClientPort : int)
loop
if Net.LineAvailable (outgoingConnection) then
get : outgoingConnection, newClientPort
exit
end if
end loop
end waitForChar
proc clientConnect (var newClientPort : int)
var clientAddress : string := Net.LocalAddress
var serverPort : int := 65
var connect : boolean := false
loop
put "Created by Blake Mesdag"
put "Enter the server address: "
get serverAddress
put "Enter your nickname: "
get nickName
if nickName = "" or nickName = " " then
nickName := "uknown" + intstr (Rand.Int (1, 9)) + intstr (Rand.Int (1, 9)) + intstr (Rand.Int (1, 9)) + intstr (Rand.Int (1, 9))
end if
for decreasing i : 5 .. 1
outgoingConnection := Net.OpenConnection (serverAddress, serverPort)
if outgoingConnection > 0 then
put : outgoingConnection, clientAddress
waitForChar (newClientPort)
Net.CloseConnection (outgoingConnection)
connect := true
exit
else
put "Retrying Connection...", i
connect := false
end if
end for
if connect = false then
put "Connection was not completed."
else
put "Connection was completed."
end if
exit when connect = true
end loop
end clientConnect
proc clientChatConnect (newClientPort : int)
var clientAddress : string := Net.LocalAddress
outgoingConnection := Net.OpenConnection (serverAddress, newClientPort)
put : outgoingConnection, clientAddress
put : outgoingConnection, nickName
end clientChatConnect
proc sendToServer (text : string)
if text = "exit" then
put : outgoingConnection, text
EXIT := true
else
put : outgoingConnection, text
GUI.SetText (chatTextSendBox, "")
end if
end sendToServer
proc sendToServer2
var text : string := GUI.GetText (chatTextSendBox)
if text = "exit" then
put : outgoingConnection, text
EXIT := true
else
put : outgoingConnection, text
GUI.SetText (chatTextSendBox, "")
end if
end sendToServer2
var newClientPort : int := 0
process receiveText
var text : string
loop
exit when EXIT = true
if Net.CharAvailable (outgoingConnection) then
get : outgoingConnection, text : *
GUI.AddLine (chatTextBox, text)
GUI.Refresh
end if
end loop
end receiveText
clientConnect (newClientPort)
clientChatConnect (newClientPort)
var font1 : int := Font.New ("Arial:10")
cls
chatTextSendBox := GUI.CreateTextFieldFull (5, 5, 320, "", sendToServer, 0, font1, 0)
var chatTextSendButton : int := GUI.CreateButton (335, 1, 20, "Send", sendToServer2)
chatTextBox := GUI.CreateTextBox (5, 30, 320, 310)
fork receiveText
loop
exit when GUI.ProcessEvent or EXIT = true
end loop
put : outgoingConnection, "exit"
Net.CloseConnection (outgoingConnection)
delay (250)
Window.Close (w1)
|
SERVER:
code: |
put "Created by Blake Mesdag"
put "Chat Server Started on ", Net.LocalAddress
put ""
const minPort := 20000
const maxPort := 65000
proc waitForChar (incomingConnection : int)
loop
if Net.LineAvailable (incomingConnection) then
exit
end if
end loop
end waitForChar
proc acceptIncoming (clientPort : int)
var port : int := 65
var serverAddress : string := Net.LocalAddress
var clientAddress : string := ""
var incomingConnection : int
var connect : boolean := false
loop
incomingConnection := Net.WaitForConnection (port, serverAddress)
if incomingConnection > 0 then
waitForChar (incomingConnection)
get : incomingConnection, clientAddress : *
put "Client: ", clientAddress, " Connecting on port: ", clientPort
put : incomingConnection, clientPort
Net.CloseConnection (incomingConnection)
connect := true
else
put "Last client failed to connect."
connect := false
end if
exit when connect = true
end loop
end acceptIncoming
proc serverChatConnect (clientPort : int, var clientAddr : string, var clientNick : string, var incomingConnection : int)
var serverAddress : string := Net.LocalAddress
incomingConnection := Net.WaitForConnection (clientPort, serverAddress)
waitForChar (incomingConnection)
get : incomingConnection, clientAddr
waitForChar (incomingConnection)
get : incomingConnection, clientNick
end serverChatConnect
var clientAddr : array minPort .. maxPort of string
var clientNick : array minPort .. maxPort of string
var text : string := ""
var incomingConnection : array minPort .. maxPort of int
for i : minPort .. maxPort
incomingConnection (i) := 0
end for
proc relayText (clientPort : int)
for i : minPort .. maxPort
if incomingConnection (i) not= 1 and incomingConnection (i) <= 0 then
else
put : incomingConnection (i), clientNick (clientPort) + " says: " + text
end if
end for
end relayText
proc relayServerMessage (clientPort : int, text : string)
for i : minPort .. maxPort
if incomingConnection (i) not= 1 and incomingConnection (i) <= 0 then
else
put : incomingConnection (i), clientNick (clientPort) + " has " + text
end if
end for
end relayServerMessage
process acceptText (clientPort : int)
var exitText : string := " exited."
var connectedText : string := " connected."
relayServerMessage (clientPort, connectedText)
loop
waitForChar (incomingConnection (clientPort))
get : incomingConnection (clientPort), text : *
if text not= "exit" then
put "Client ", clientAddr (clientPort), " with nickname ", clientNick (clientPort), " on port ", clientPort, " sent: ", text
relayText (clientPort)
elsif text = "exit" then
put "Client ", clientAddr (clientPort), " with nickname ", clientNick (clientPort), " on port ", clientPort, " has exited."
relayServerMessage (clientPort, exitText)
Net.CloseConnection (incomingConnection (clientPort))
incomingConnection (clientPort) := 0
end if
exit when text = "exit"
end loop
clientAddr (clientPort) := ""
end acceptText
var clientPort : array minPort .. maxPort of int
for i : minPort .. maxPort
clientPort (i) := i
clientAddr (i) := ""
end for
loop
for indexPort : minPort .. maxPort
if clientAddr (indexPort) = "" then
acceptIncoming (clientPort (indexPort))
serverChatConnect (clientPort (indexPort), clientAddr (indexPort), clientNick (indexPort), incomingConnection (indexPort))
fork acceptText (clientPort (indexPort))
exit
else
end if
end for
end loop
|
By the way, this program has actually been put into use. My district now uses it for a teleconferencing class. |
|
|
|
|
|
|
|