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. | 
			 
			
				 | 
			 
		  | 
	 
	 
		 | 
		
		 | 
	 
	  
		  | 
	 
				 
		 | 
	 
 
	
	
	 
	
	 |