Program for communicating over the Internet in Delphi. Chat for local network. We write our bike in Delphi

Good afternoon, Habrauser. I’ll be honest, I love the Delphi language, and I think that it has been unjustifiably forgotten. And in this topic, I would like to share with you my experience of writing a chat. This is not a very complicated matter, but very, very funny.

Introduction.

To write this very chat, I used the IDE Borland Delphi 7 Lite assembly. All the libraries that were needed were already included.

Part I. Writing the interface.

Actually this part is the easiest. First, we need to think about how our chat will work. I settled on manually selecting the port, server address, and nickname. In principle, you can choose the port yourself and specify it in the source code, but this way we can run as many copies of the program as we want in server mode until we run out of ports. So, we create four input fields, one Memo type element, and three buttons. Don't forget to add two sockets, server and client. We write text on buttons. Program name, icon. Etc. This concludes the first part.

Part 2. Internalities.

In principle, there is not much work here, but it is all important. First, we write the code for the buttons. It's below.

procedure TForm1. Button1Click(Sender: TObject);
begin
button2. Enabled: = false; // Disable the server button
Clsocket. address := edit1. Text ;
Clsocket. Port: = StrtoInt(edit2.Text); //Write down the port and IP
Clsocket. Active: = true; //Enable the socket
Clsocket. Open ; // Open it
button3. enabled := true ; //Unlock the send button
end ;

And about the same for all the other buttons.

You don't need anything for the input fields.

Separately, I want to consider writing the code for the send message button because it is very important.

procedure TForm1. Button3Click(Sender: TObject);
var f: integer ; today : TdateTime ;
begin
today : = now ; //Find out the time
s1:=edit4. Text ; //Form a line with nickname and sending time
s2:=edit3. Text ;
s3: = "[" + s2+ "] (" + TimetoStr(today) + ") :" + s1; //Glue everything together
ifclsocket. active = true then
ClSocket. Socket. SendText(s3) //Send a string to the server
else
begin
for f: = 0 to SrSocket. Socket. ActiveConnections - 1 do //Send on behalf of the server to all clients
begin
Srsocket. Socket. Connections[f]. SendText(s3);
end ;
Memo1. lines. add(s3); // Write down the chat date for yourself
end ;
edit4. text : = "" ;
end ;

And finally, we write the connection/disconnection/reception code. Here it is important not to forget to link events to procedures.

procedure TForm1. SrsocketClientRead(Sender: TObject;

var i: integer ;
begin
Received: = Socket. ReceiveText(); //Transfer the received text to a variable
for i: = 0 to SrSocket. Socket. ActiveConnections - 1 do //Send the received information to all connected clients
Srsocket. Socket. Connections[i]. SendText(Received);
memo1. Lines. add (Received) ; //Write it down for ourselves
end ;

procedure TForm1. SrSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1. Lines. Add ( "The client has disconnected") ; //Just notify the server
end ;

procedure TForm1. SrSocketClientConnect (Sender: TObject ; Socket: TCustomWinSocket) ;
begin
Memo1. Lines. Add ( "The client has connected") ;
end ;

Part 3. Final tests.

This part is the shortest. In the project settings, add a name, version, build, and draw an icon.

Also, after some searching on the Internet, I found this code for specifying the IP address, and included it in my chat.

function GetLocalIP: String ;
const WSVer = $101 ;
var
wsaData: TWSAData;
P:PHostEnt;
Buf: array [ 0.. 127] of Char ;
begin
Result : = "" ;
if WSAStartup(WSVer, wsaData) = 0 then begin //I don’t want to comment on anything here, because... I'm not entirely sure how it works
if GetHostName(@ Buf, 128 ) = 0 then begin
P : = GetHostByName(@Buf) ;
if P<>nil then
Result : = iNet_ntoa(PInAddr(p^ . h_addr_list ^ ) ^ ) ;
end ;
WSACleanup;
end ;
end ;

Actually, this is the entire chat. As you can see, writing it is very simple. And I’m just grateful to you for respecting this post.

Have a good day!

Tags: Delphi, programming

new player July 4, 2012 at 6:26 pm

We write our bike in Delphi

  • Lumber room *

Good afternoon, Habrauser. I’ll be honest, I love the Delphi language, and I think that it has been unjustifiably forgotten. And in this topic, I would like to share with you my experience of writing a chat. This is not a very complicated matter, but very, very funny.

Introduction.

To write this very chat, I used the IDE Borland Delphi 7 Lite assembly. All the libraries that were needed were already included.

Part I. Writing the interface.

Actually this part is the easiest. First, we need to think about how our chat will work. I settled on manually selecting the port, server address, and nickname. In principle, you can choose the port yourself and specify it in the source code, but this way we can run as many copies of the program as we want in server mode until we run out of ports. So, we create four input fields, one Memo type element, and three buttons. Don't forget to add two sockets, server and client. We write text on buttons. Program name, icon. Etc. This concludes the first part.

Part 2. Internalities.

In principle, there is not much work here, but it is all important. First, we write the code for the buttons. It's below.

procedure TForm1. Button1Click(Sender: TObject);
begin
button2. Enabled: = false; // Disable the server button
Clsocket. address := edit1. Text ;
Clsocket. Port: = StrtoInt(edit2.Text); //Write down the port and IP
Clsocket. Active: = true; //Enable the socket
Clsocket. Open ; // Open it
button3. enabled := true ; //Unlock the send button
end ;

And about the same for all the other buttons.

You don't need anything for the input fields.

Separately, I want to consider writing the code for the send message button because it is very important.

procedure TForm1. Button3Click(Sender: TObject);
var f: integer ; today : TdateTime ;
begin
today : = now ; //Find out the time
s1:=edit4. Text ; //Form a line with nickname and sending time
s2:=edit3. Text ;
s3: = "[" + s2+ "] (" + TimetoStr(today) + ") :" + s1; //Glue everything together
ifclsocket. active = true then
ClSocket. Socket. SendText(s3) //Send a string to the server
else
begin
for f: = 0 to SrSocket. Socket. ActiveConnections - 1 do //Send on behalf of the server to all clients
begin
Srsocket. Socket. Connections[f]. SendText(s3);
end ;
Memo1. lines. add(s3); // Write down the chat date for yourself
end ;
edit4. text : = "" ;
end ;

And finally, we write the connection/disconnection/reception code. Here it is important not to forget to link events to procedures.

procedure TForm1. SrsocketClientRead(Sender: TObject;

var i: integer ;
begin
Received: = Socket. ReceiveText(); //Transfer the received text to a variable
for i: = 0 to SrSocket. Socket. ActiveConnections - 1 do //Send the received information to all connected clients
Srsocket. Socket. Connections[i]. SendText(Received);
memo1. Lines. add (Received) ; //Write it down for ourselves
end ;

procedure TForm1. SrSocketClientDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
Memo1. Lines. Add ( "The client has disconnected") ; //Just notify the server
end ;

procedure TForm1. SrSocketClientConnect (Sender: TObject ; Socket: TCustomWinSocket) ;
begin
Memo1. Lines. Add ( "The client has connected") ;
end ;

Part 3. Final tests.

This part is the shortest. In the project settings, add a name, version, build, and draw an icon.

Also, after some searching on the Internet, I found this code for specifying the IP address, and included it in my chat.

function GetLocalIP: String ;
const WSVer = $101 ;
var
wsaData: TWSAData;
P:PHostEnt;
Buf: array [ 0.. 127] of Char ;
begin
Result : = "" ;
if WSAStartup(WSVer, wsaData) = 0 then begin //I don’t want to comment on anything here, because... I'm not entirely sure how it works
if GetHostName(@ Buf, 128 ) = 0 then begin
P : = GetHostByName(@Buf) ;
if P<>nil then
Result : = iNet_ntoa(PInAddr(p^ . h_addr_list ^ ) ^ ) ;
end ;
WSACleanup;
end ;
end ;

Actually, this is the entire chat. As you can see, writing it is very simple. And I’m just grateful to you for respecting this post.

Have a good day!

Tags: Delphi, programming


I think the idea of ​​creating your own (corporate) chat has come to you more than once. The same idea came to me, and as always, I started looking for information on the Internet, but I didn’t find anything good. Everything somehow does not fully describe how this can be done.

And I promised myself that as soon as I study it, I will post complete information on this topic. I made my chat on sockets. You can communicate using them both over the Internet and over a local network. To do this, you just need to know the IP address. Programmed in Delphi7.

Installing Prerequisites

Since I did it on delphi7, the components I needed were not there by default. ( ServerSocket1, ClientSocket1).
To do this you need to add Socket components.

Go to the menu Component --> Install Packages...--> Add --> dclsockets70.bpl

And we indicate the path to the package with components, it is located in the Delphi root folder in the Bin package. I had it in:

C:\Program Files\Borland\Delphi7\Bin\ dclsockets70.bpl

After this addition, these components should appear in your Internet tab.

Placing Components and Writing Code

I added the following elements to the form: ServerSocket1, ClientSocket1, Edit1 (for chat), Edit2 (for the server IP address), Memo1 to display a message, and 3 buttons.

To create a Server, write the following thing to the event in the button:

function GetLocalIP: String;
const WSVer = $101;
var
wsaData: TWSAData;
P:PHostEnt;
Buf: array of Char;
begin
Result:= "";
if WSAStartup(WSVer, wsaData) = 0 then begin
if GetHostName(@Buf, 128) = 0 then begin
P:= GetHostByName(@Buf);
if P<> nil then
Result:= iNet_ntoa(PInAddr(p^.h_addr_list^)^);
end;
WSACleanup;
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ServerSocket1.Port:=65000; // Port of your server, set any one you like
ServerSocket1.Active:=True; // activate the server
ServerSocket1.Open; //start
ShowMessage("Your IP: "+GetLocalIP); //we give out our IP address so that the client can connect to us
end;

Once the server has been turned on, the client will be able to connect to the server.
To do this, he enters the server’s IP address in Edit2, and presses the connect button:

procedure TForm1.Button2Click(Sender: TObject);
begin
ClientSocket1.Address:=Edit2.Text; // Server IP address
ClientSocket1.Port:=65000; //its port
ClientSocket1.Active:=True; //activate the client
ClientSocket1.Open; //start
end;

Attention: The Client can only send a message, and the Server, in turn, can receive. For two-way communication, enable Client and Server on two programs at different ends of the network.

To read a message, the server has a wait for the message to be received...here it is

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
Socket: TCustomWinSocket);
begin
memo1.Lines.add(Socket.RemoteAddress+": ");
memo1.Lines.add(Socket.ReceiveText);
StatusBar1.Panels.Items.Text:=Socket.RemoteAddress;
end;

To send the message I wrote in two procedures. Here they are:

procedure TForm1.SendMes(Text: String);
begin
if form1.ServerSocket1.Active then
if form1.ServerSocket1.Socket.ActiveConnections>0 then
form1.ServerSocket1.Socket.Connections.SendText(Text);

if form1.ClientSocket1.Active then
form1.ClientSocket1.Socket.SendText(Text);
end; procedure TForm1.Button1Click(Sender: TObject);
begin
SendMes(Edit1.Text);
memo1.Lines.add(GetLocalIP+": ");
memo1.Lines.add(Edit1.Text);
end;

Some of the readers, looking at the title of the section, may be indignant and ask: “What is the connection between X-Coding and a simple chat?” Basically, there is no connection. Chat is a simple program that works with the network. I know that you can’t put everything under the same brush, and if some utility uses the network, this does not mean that it is a hacker. But still, I will describe here the creation of the chat, because we will build it on a fundamentally different protocol than usual. In any case, this knowledge will not be superfluous.

But we'll talk about chat a little later, but now a little theory.

At the moment there are two main protocols: TCP and UDP. Previously, IPX was still very common, which was used by Novell. But at the moment it is moving away, and you rarely see such an animal anymore. Only on older systems you can see IPX. Most of the other protocols you know (FTP, HTTP, POP3, SMTP, etc.) run on top of TCP or UDP.

What does it mean: "on top of another protocol"? TCP implements the basic functions for working with a network. It can establish a connection with a remote computer, transmit and receive data, and check whether the server received sent packets correctly. Let's say we want to create a file transfer protocol (FTP). To do this, we take TCP, endow it with the capabilities we need and - get it - sign it. So it turns out that FTP works through (on top of) the TCP protocol. If we want to create FTP from scratch, we will have to re-implement the connection setup and data transfer functions. And so you only need to prepare the data in a special format (FTP protocol) and give it to the TCP protocol, which itself will establish a connection and send this data where it is needed.

If you are familiar with Delphi firsthand and have at least a little understanding of OOP theory, then you have already noticed the analogy with object-oriented programming. This is exactly the principle that the network operates on. This whole thing is standardized, and if you want to find out more, read some documentation about the OSI (Open Systems Interconnection) model and its seven levels (here I can send it again to my website or see Section 4.1 of this book). This topic is quite interesting, and in any case it is advisable to know the structure of the protocols.

The UDP protocol is very similar to TCP. It also implements data transfer capabilities, but it does not establish connections and does not maintain the integrity of the transmitted data. The protocol simply opens a port, throws a portion of data there and does not even worry about whether it reaches the recipient or not. Therefore, UDP is much faster than TCP.

If you want to work with this protocol, you will have to implement verification of the correctness of data receipt yourself. Therefore, to transfer files or other large information, you must choose TCP, because if even one small piece of the file is lost, it will not be recovered. Well, for the chat that we will write today, UDP will be a more convenient option. It is very fast and very efficient for small message sizes.

In Delphi, the library is well suited for working with

I think she will soon become your best friend.

The theory is over, let's move on to writing the chat. Stretch your fingers, mouse, keyboard and launch Delphi. Now we will start my favorite activity - programming. We will need 3 components on the form.

□ Tmeto component. It can be stretched to almost the entire shape.

□ The TEdit component, into which we will write the message to be sent.

□ TButton, when pressed, the message will be sent. In Fig. Figure 4.21 shows the form of the future chat.

To work with ports, we need the components idUDPClient (can send data, Fig. 4.22) from the Indy Clients tab and idUDPServer (can receive data, Fig. 4.23) from the My Servers tab. Transfer one such component to the form.

Fig, 4.22. idUDPCiient component properties

Rice. 4.23. idUDPServer component properties

Now we need to configure the protocol and O R. The first thing we will do is select any port from 1 to 65,000 through which communication will occur. I decided to choose 11245 (you can choose any other). Assign this value to the Port property of the idUDpc client component and the De fault Port property of the idUDPServer component. This will force the client and server to run on the same port, which is necessary for communication to work.

REMEMBER!!! UDP protocol ports do not overlap with TCP ports. This means that TCP port 80 is not equal to UDP port 80.

Now the client (idüDPCilent) needs to specify the Host property. The IP address of the computer to which messages will be sent is recorded here. But our chat and messages should be received by all users in the network who have launched the program. Therefore, to avoid problems, it is advisable to set BroadcastEnabled equal to true for both components. A Instead of a specific IP address, use a broadcast address (an address that everyone receives). If you use addresses like 192,168,100.x in your network, then your broadcast address will be 192.168.100.255 (we change the last octet to 255).

The preparations are complete, you can program.

Create a button event handler and write the following code there:

Procedure TForml.ButtonlClick(Sender: TObject); begin IdUDPClientl.Send(Editl.Text); end;

There is just one line that sends the contents of the input line (component) using a UDP client

Now we need to teach the UDP server to receive this information. To do this, create an OnUDPRead event handler FOR the idUDPServer component. Write the following in it:

Procedure TForml. IdODPServerlüDPRead(Sender: TObject; ÄEata: TStream; ABrnding: TIdSocketHandle);

var StringFormatedStream: TStringStream; s:String; begin //Initialization

StringFormatedStream: = TStringStream.Create(""); //Copying from a simple stream to a string StringFormatedStream.CopyFrom(AData, AData.Size);

//Output the received message

Memol.Lines.Add(ABinding.PeerIP+" "+StringFormatedStream.DataString);

ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s , Length(s)); //Free the string stream StringFormatedStream.Free; end;

The event handler procedure has three parameters. The first one is present in all handlers and does not contain anything interesting for us. The second is data that is received from the network. Third, it stores information about where the data came from.

So, the received data is stored in the second parameter. They come to us as a simple unformatted TStream. To make it more convenient to work with data, it is better to transfer it to a string stream. Do you think this is inconvenient? What if you pass not text, but an image, and the component formats it into text? Now this will no longer be inconvenient, but a complete bummer!

See how easily everything turns into text. The handler declares one Variable StringFormatedStream of type TStringStream (string stream). The first line of code initializes it. The second line copies data from a simple raw stream to a string stream. All!!! Now the passed text is in the Datastring property of the StringFormatedStream. After THIS, feel free to OUTPUT this result in the Memo component.


Fig.4.24. Chat in action

But we are writing a chat, and it would be desirable to display information about who sent this text. For example, the IP address of the data sender is displayed, which is located in the repe property of the third ABinding parameter. But this is just an example, and in a real program it will look ugly. What is Mr. 192.168.100.x talking about? Or maybe it’s even the lady who’s talking. Therefore, you can add the sender's name directly to the sending text. The code will change as follows:

IdUDPClisntl. Send("Put the sender's name here" Editl.Text); You can allow the user to enter a name in a separate Edit2 input line. In this case the code will be like this; IdUDPClisntl.Send(Edit2.Text+" "+Editl.Text);

On the CD in the directory \Examples\Chapter 4\Chat you can see an example of this program.

In this topic I would like to write in detail how to create the simplest ICQ chat in Delphi!

What we need for this:
1.Delphi (best to use 7)
2. Installed TICQ component.
3. Straight arms.

Let's get started!
And so we create a new project in Delphi and throw the TICQ component on the form.
We throw Memo1, EDit1,Edit2,button1,ListBox1,L istBox2 on the form.
Explanation:
Memo1 - chat log
Edit1 - UIN
Edit2 - password
button1 - connection
ListBox1 - online user
ListBox2 - reg user

Button1:

Procedure TForm1.Button1Click(Sender: TObject); begin ICQClient1.UIN:=StrToInt(Edit1.Text); ICQClient1.Password:=Edit2.Text; icqclient1.Login(); end;

The ICQClient1MessageRecv1 event should look like this:

Procedure TForm1.ICQClient1MessageRecv1(Sender: TObject; Msg, UIN: String); begin Memo1.Lines.Add(trim(nick(UIN))+": "+Msg); //log if Msg<>"!" then //if the message starts with "!" do not throw begin if OnLine(UIN) into the chat<>-1 then //checking whether the user is in the chat Send(Msg,UIN) //if in the chat then accepts messages in the chat else if Reged(UIN)=-1 then//checking for registration icqclient1.SendMessage(StrToInt(UIN), "welcome to the chat!" + #13#10 + "to register, enter!reg<ваш ник>") else begin icqclient1.SendMessage(StrToInt(UIN), "To enter the chat, use the command!chat" + #13#10 + "For help, send!help") //user is not in the chat! end; end else Command( UIN,Msg); //chat commands!

Online function:

Function TForm1.OnLine(UIN:string):integer; var i:integer; begin OnLine:=-1; for i:=0 to ListBox1.Items.Count-1 do if Trim(Copy(ListBox1.Items[i],4,9))=UIN then //UIN length OnLine:=i; end;

Sending messages to chat:

Procedure TForm1.Send(Msg,UIN:string); var i2:integer; i:integer; Str,Str2:string; begin Str2:=ListBox1.Items; for i:=0 to ListBox1.Items.Count-1 do begin if i2=5 then begin Sleep(2000); i2:=0; end; if OnLine(UIN)<>i then begin i2:=i2+1; Str:=ListBox1.Items[i]; if Trim(Copy(Str,1,2))=Trim(Copy(Str2,1,2)) then icqclient1.SendMessage(StrToInt(Copy(ListBox1.Items[i],4,9)), nick(UIN) +": "+Msg); end; end; end;

Nick Function:

Function TForm1.nick(UIN:string):string; begin if Reged(UIN)<>-1 then nick:=TRIM(Copy(ListBox2.Items,13,50)) end

Reged function:

Function TForm1.Reged(UIN:string):integer; var i:integer; beginReged:=-1; for i:=0 to ListBox2.Items.Count-1 do if Copy(ListBox2.Items[i],4,9)=UIN then Reged:=i; end;

And finally the Command procedure (chat commands):

Procedure TForm1.Command(UIN,Msg:string); var i,i1,razdel:integer; command,key,key2:string; Str:string; help: TStrings; begin try section:=0; for i:=1 to Length(Msg) do begin help:= TStringList.Create; help.LoadFromFile("command/help.txt"); //Open a file with text if (Msg[i]=" ") and (razdel=0) then razdel:=i; end; if divide<>0 then begin command:=Copy(Msg,1,razdel-1); key:=Copy(Msg,razdel+1,Length(Msg)); key2:=Copy(Msg,razdel+1,Length(Msg)); end else begin command:=Msg; key:=""; end; if (command="!chat") or (command = "!chat") then begin ListBox1.Items.Append(ListBox2.Items); icqclient1.SendMessage(StrToInt(UIN), "you are logged in"); end; if (command = "!help") or (command ="!help") then begin if OnLine(UIN)<>-1 then begin icqclient1.SendMessage(StrToInt(UIN), help.Text); end else icqclient1.SendMessage(StrToInt(UIN), "To use commands, enter the chat!"); end; //end; if (command="!exit") or (command = "!Exit") or (command = "!EXIT") then begin ListBox1.Items.Delete(OnLine(UIN)); end; if (command="!reg") or (command="!nick") or (command="!REG") and (key<>"") then begin if Reged(UIN)<>-1 then icqclient1.SendMessage(StrToInt(UIN), "You are already registered in the chat!:)") else if (Length(Trim(key))>15) then icqclient1.SendMessage(StrToInt(UIN), "Nickname too long , It must be more than 3 and less than 15 characters long, and must not contain spaces") else if (Length(Trim(key))<3) then icqclient1.SendMessage(StrToInt(UIN), "Слишком короткий ник, Он должен быть длинной,больше 3 и менее 15 символов, не должен сожержать пробелов") else //if (Length(Trim(UIN))<9) then //icqclient1.SendMessage(StrToInt(UIN), "Ваш уин не подходит для регистрации!") //else begin ListBox2.Items.Append("0 "+UIN+" "+Trim(Key)); icqclient1.SendMessage(StrToInt(UIN), "Вы успешно зарегистрировались!Для входа в чат наберите!чат"); ListBox2.Items.SaveToFile("user/user.txt"); end; end; //end; except end; end;