Send string via Winsock fails - winsock

I want to send some text from Client to server, but the receiver just hangs and nothing goes thru.
Client
program client;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes , SysUtils, Windows, Winsock
{ you can add units after this };
procedure GetInformation();
var
_wsdata: WSAData;
result:Integer;
serverSocket, S: TSocket;
_addrIn, _addr: sockaddr_in;
addrSize: Integer;
tid: Cardinal;
SendBuf:Array[0..31] of AnsiChar;
data : Integer;
begin
//result := false;
if WSAStartup(MakeWord(2, 2), _wsdata) <> 0 then
Exit;
serverSocket := socket(AF_INET, SOCK_STREAM, 0);
if serverSocket = INVALID_SOCKET then
Exit;
_addrIn.sin_family := AF_INET;
_addrIn.sin_addr.S_addr := INADDR_ANY;
_addrIn.sin_port := htons(8080);
if bind(serverSocket, _addrIn, SizeOf(_addrIn)) = SOCKET_ERROR then
Exit;
if listen(serverSocket, SOMAXCONN) = SOCKET_ERROR then
Exit;
addrSize := SizeOf(_addrIn);
getsockname(serverSocket, _addrIn, addrSize);
Writeln(Format('Listening on port %d' + #13#10, [ntohs(_addrIn.sin_port)]));
while True do
begin
S := accept(serverSocket, #_addr, #addrSize);
data := recv(s,SendBuf,Length(SendBuf),0);
Writeln('Data Received: ',data);
end;
// result := True;
end;
begin
GetInformation();
ReadLn;
end.
Now the sender which is supposed to send the data Works fine, it's just the Receiver. It looks like this
Server
program server;
{$mode delphi}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes , Windows , Winsock , SysUtils
{ you can add units after this };
procedure SendFullnameTest();
var
MyData:WSADATA;
result:Integer;
s:TSocket;
SendBuf:Array[0..31] of AnsiChar;
clientservice:sockaddr_in;
BytesSent:Integer;
begin
try
result:= WSAStartup(MAKEWORD (2,2), MyData);
if result = NO_ERROR then
begin
s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if s <> INVALID_SOCKET then
begin
clientservice.sin_family := AF_INET;
clientservice.sin_addr.s_addr := inet_addr('127.0.0.1');
clientservice.sin_port := htons(8080);
if connect(s,clientservice,sizeof(clientservice)) <> SOCKET_ERROR then
begin
sendbuf := 'I am a Sent message';
bytesSent := send(s,sendbuf,Length(sendbuf),0);
writeln('Bytes send: ',bytesSent);
end else
writeln('Failed to connect');;
end else
writeln('Error at Socket: ',WSAGetLastError);;
end else
writeln('Error at WSAStartup');
finally
Writeln(SysErrorMessage(GetLastError));
WSACleanUp;
Readln;
end;
end;
begin
SendFullnameTest();
ReadLn;
end.
The annoying thing is it just doesn't show if it sends, neither does it show if it received.
I just get this as end point

Related

Sending an Email in Delphi using Indy... SSL Negotiation Failed [duplicate]

I try to send eMail with the code below (taken from http://delphiprogrammingdiary.blogspot.com/2014/12/how-to-send-email-in-delphi.html) without success.
Constantly I receive the error ("socket error 10054 connection reset by peer" twice and finally "SSL negotiation failed") at the statement "Send(IdMessage1)" although client is successfully connected with server.
procedure SendEmailClick(Sender: TObject);
var
IdMessage1: TIdMessage;
Attachmentfile: TIdAttachmentFile;
begin
// IO HANDLER SETTINGS //
With TIdSSLIOHandlerSocketOpenSSL.Create(nil) do
begin
Destination := 'mySrver.com:587';
Host := 'mySrver.com';
MaxLineAction := maException;
Port := 587;
SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
SSLOptions.Mode := sslmUnassigned;
SSLOptions.VerifyMode := [];
SSLOptions.VerifyDepth := 0;
end;
//SETTING SMTP COMPONENT DATA //
with TIdSMTP.Create(nil) do begin
Host := 'mySrver.com';
Port := 587;
Username := myMailAddress; // please change to your gmail address //
Password := myPassword;
IOHandler := TIdSSLIOHandlerSocketOpenSSL.create;
AuthType := satDefault;
UseTLS := utUseExplicitTLS;
// SETTING email MESSAGE DATA //
IdMessage1:= TIdMessage.Create(nil);
IdMessage1.Clear;
// add recipient list //
with IdMessage1.Recipients.Add do
begin
Name := 'Recipient 1';
Address := recipient1Address; // please change email address as required //
end;
//add Attachment to mail //
Attachmentfile := TIdAttachmentFile.Create(IdMessage1.MessageParts,'Τιμολόγιο 659.PDF');
IdMessage1:= TIdMessage.Create(nil);
IdMessage1.From.Address := myMailAddress; // please change to your gmail address //;
IdMessage1.Subject := 'Test Email Subject';
IdMessage1.Body.Add('Test Email Body');
IdMessage1.Priority := mpHigh;
TRY
Connect(); // no problem here. it connects always
Send(IdMessage1); // raises the error SSL negotiation failed
ShowMessage('Email sent');
Disconnect();
except on e:Exception do
begin
ShowMessage(e.Message);
Disconnect();
end;
END;
IdMessage1.Free;
IOHandler.Free;
end;
AttachmentFile.Free;
end;
Can you help me please ?
PS1. The same problem raises with any MAPI server (myServer, GMail, Yahoo etc)
PS2. The SSL DLLs are present and they are used by the same application to connect for other purpose without this problem.
You are creating a TIdSSLIOHandlerSocketOpenSSL object and configuring it, but then you discard and leak it and then create and use another TIdSSLIOHandlerSocketOpenSSL object with default settings. Get rid of the second object, use the first object instead.
You are also creating 2 TIdMessage objects, as well. Get rid of the second one.
Also, you don't need to set the Host, Port, and Destination properties on the SSLIOHandler. Connect() will handle that for you.
Try this:
procedure SendEmailClick(Sender: TObject);
var
IdSMTP: TIdSMTP;
IdMessage1: TIdMessage;
Attachmentfile: TIdAttachmentFile;
IdSSL: TIdSSLIOHandlerSocketOpenSSL;
begin
//SETTING SMTP COMPONENT DATA //
IdSMTP := TIdSMTP.Create(nil);
try
IdSMTP.Host := 'mySrver.com';
IdSMTP.Port := 587;
IdSMTP.Username := myMailAddress; // please change to your gmail address
// Password := myPassword;
IdSMTP.AuthType := satDefault;
IdSMTP.UseTLS := utUseExplicitTLS;
// IO HANDLER Settings //
IdSSL := TIdSSLIOHandlerSocketOpenSSL.Create(IdSMTP);
IdSSL.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
IdSSL.SSLOptions.Mode := sslmUnassigned;
IdSSL.SSLOptions.VerifyMode := [];
IdSSL.SSLOptions.VerifyDepth := 0;
IdSMTP.IOHandler := IdSSL;
// SETTING email MESSAGE DATA //
IdMessage1 := TIdMessage.Create(nil);
try
// add recipient list //
with IdMessage1.Recipients.Add do
begin
Name := 'Recipient 1';
Address := recipient1Address; // please change email address as required //
end;
//add Attachment to mail //
Attachmentfile := TIdAttachmentFile.Create(IdMessage1.MessageParts, 'Τιμολόγιο 659.PDF');
IdMessage1.From.Address := myMailAddress; // please change to your gmail address //;
IdMessage1.Subject := 'Test Email Subject';
IdMessage1.Body.Add('Test Email Body');
IdMessage1.Priority := mpHigh;
try
IdSMTP.Connect();
try
IdSMTP.Send(IdMessage1);
ShowMessage('Email sent');
finally
IdSMTP.Disconnect();
end;
except
on e: Exception do
begin
ShowMessage(e.Message);
end;
end;
finally
IdMessage1.Free;
end;
finally
IdSMTP.Free;
end;
end;

Sending e-mail with attachments with Indy

First of all, code.
procedure TMain.SendEmailIndy(
const SMTPServer: string;
const FromName, FromAddress: string;
const ToAddresses: string; //comma "," separated list of e-mail addresses
const CCAddresses: string; //comma "," separated list of e-mail addresses
const BCCAddresses: string; //comma "," separated list of e-mail addresses
const Subject: string;
const EmailBody: string;
const IsBodyHtml: Boolean);
var
smtp: TIdSMTP; // IdSmtp.pas
msg: TidMessage; // IdMessage.pas
builder: TIdCustomMessageBuilder; //IdMessageBuilder.pas
s: string;
emailAddress: string;
FileToSend: TIdAttachmentfile;
begin
msg := TidMessage.Create(nil);
try
if IsBodyHtml then begin
builder := TIdMessageBuilderHtml.Create;
TIdMessageBuilderHtml(builder).Html.Text := EmailBody
end else begin
builder := TIdMessageBuilderPlain.Create;
end;
if (Realization.AttachmentD.FileName <> '') then begin
msg.IsEncoded := true;
FileToSend := TIdAttachmentFile.Create(msg.MessageParts, Realization.AttachmentD.FileName);
FileToSend.FileName := Realization.AttachmentD.FileName;
//FileToSend.ContentDisposition := 'attachment';
FileToSend.ContentType := 'multipart/mixed';
ShowMessage('Sent: '+Realization.AttachmentD.FileName);
end;
msg.From.Name := FromName;
msg.From.Address := FromAddress;
msg.Subject := Subject;
//If the message is plaintext then we must fill the body outside of the PlainText email builder.
//(the PlainTextBuilder is unable to build plaintext e-mail)
if not IsBodyHtml then begin
msg.Body.Text := EmailBody;
end;
for s in ToAddresses.Split([',']) do
begin
emailAddress := Trim(s);
if emailAddress <> '' then begin
with msg.recipients.Add do
begin
//Name := '<Name of recipient>';
Address := emailAddress;
end;
end;
end;
for s in CCAddresses.Split([',']) do
begin
emailAddress := Trim(s);
if emailAddress <> '' then
msg.CCList.Add.Address := emailAddress;
end;
for s in BCCAddresses.Split([',']) do
begin
emailAddress := Trim(s);
if emailAddress <> '' then
msg.BccList.Add.Address := emailAddress;
end;
smtp := TIdSMTP.Create(nil);
try
msg.Encoding := meMIME;
msg.ContentType := 'text/html';
msg.CharSet := 'UTF-8';
msg.ContentTransferEncoding:= 'quoted-printable';
smtp.Host := SMTPServer; // IP Address of SMTP server
Smtp.UseTLS := utNoTLSSupport;
smtp.Port := 587; //The default already is port 25 (the SMTP port)
smtp.Username := _GlobalData.EMail;
smtp.Password := _GlobalData.Password;
smtp.Connect;
try
smtp.Send(msg);
ShowMessage('Wiadomość wysłana.');
Realization.AttachmentD.FileName := '';
finally
smtp.Disconnect();
end;
finally
smtp.Free;
end;
finally
msg.Free;
end;
end;
I experience problems with sending e-mail message with attached file to it.
When I remove the following line from the code above, the message is sent without html message (e-mail body) that should be there:
FileToSend.ContentType := 'multipart/mixed';
However, when I leave this line in the code and try to send a message, I receive this message:
A policy-violation was found in an Email message you sent.
This Email scanner intercepted it and stopped the entire message
reaching its destination.
The policy-violation was reported to be:
Disallowed breakage found in header name - not valid email
Please contact your IT support personnel with any queries regarding this
policy.
Therefore my question is, how to send an e-mail with attached file properly.
You are misusing the TIdMessageBuilder... classes (TIdMessageBuilderHtml is perfectly capable of creating plain-text emails, but more importantly you are not calling TIdCustomMessageBuilder.FillMessage() to transfer the builder data into the TIdMessage).
You are not populating the TIdMessage correctly (for instance, you are not setting the TIdMessage.ContentType and TIdAttachmentFile.ContentType properties correctly when an attachment is present).
Try something more like this instead:
procedure TMain.SendEmailIndy(
const SMTPServer: string;
const FromName, FromAddress: string;
const ToAddresses: string; //comma separated list of e-mail addresses
const CCAddresses: string; //comma separated list of e-mail addresses
const BCCAddresses: string; //comma separated list of e-mail addresses
const Subject: string;
const EmailBody: string;
const IsBodyHtml: Boolean);
var
smtp: TIdSMTP; // IdSmtp.pas
msg: TidMessage; // IdMessage.pas
builder: TIdMessageBuilderHtml; //IdMessageBuilder.pas
begin
msg := TidMessage.Create(nil);
try
builder := TIdMessageBuilderHtml.Create;
try
if IsBodyHtml then
begin
builder.Html.Text := EmailBody;
builder.HtmlCharSet := 'utf-8';
builder.HtmlContentTransfer := 'quoted-printable';
end else
begin
builder.PlainText.Text := EmailBody;
builder.PlainTextCharSet := 'utf-8';
builder.PlainTextContentTransfer := 'quoted-printable';
end;
if Realization.AttachmentD.FileName <> '' then
begin
builder.Attachments.Add(Realization.AttachmentD.FileName);
ShowMessage('Sending: ' + Realization.AttachmentD.FileName);
end;
builder.FillMessage(msg);
finally
builder.Free;
end;
msg.From.Name := FromName;
msg.From.Address := FromAddress;
msg.Subject := Subject;
msg.Recipients.EmailAddresses := ToAddresses;
msg.CCList.EmailAddresses := CCAddresses;
msg.BccList.EmailAddresses := BCCAddresses;
smtp := TIdSMTP.Create(nil);
try
smtp.Host := SMTPServer; // IP Address of SMTP server
Smtp.UseTLS := utNoTLSSupport;
smtp.Port := 587; //The default already is port 25 (the SMTP port)
smtp.Username := _GlobalData.EMail;
smtp.Password := _GlobalData.Password;
smtp.AuthType := satDefault;
smtp.Connect;
try
smtp.Send(msg);
finally
smtp.Disconnect;
end;
finally
smtp.Free;
end;
finally
msg.Free;
end;
ShowMessage('Wiadomość wysłana.');
Realization.AttachmentD.FileName := '';
end;

Sending emails from the USA

My program uses Indy 10 TIdSMTP and TIdMessage to send error reports via email. The program is used mainly in Germany, but some clients are in the USA.
The tool works flawlessly in Germany, but the USA clients are not able to send anything at all. The output shows that the connection to the German email server (smtp.web.de) is made, but after that, an immediate disconnect follows. The exception "Socket error #10054 connection reset by peer" is thrown.
Here's some code:
procedure SendMail(const PI_sSenderAddress: string; const PI_arrReceiverAddresses, PI_arrCCAddresses, PI_arrBCCAddresses: array of string; const PI_sSubject, PI_sMailText: string; const PI_arrAttachments: array of string; const PI_sHost: string = ''; const PI_sUsername: string = ''; const PI_sPassword: string = ''; const PI_bUseTLS: boolean = False; const PI_nPort: integer = 25; const PI_nTimeoutSeconds: integer = 5 );
var
smtp: TIdSMTP;
Mail: TIdMessage;
i: integer;
arrAttachments: array of TIdAttachmentFile;
io: TIdSSLIOHandlerSocketOpenSSL;
begin
io := nil;
smtp := TIdSMTP.Create(Application);
try
smtp.Password := PI_sPassword;
smtp.Username := PI_sUsername;
smtp.Port := PI_nPort;
smtp.Host := PI_sHost;
if PI_bUseTLS then begin
io := TIdSSLIOHandlerSocketOpenSSL.Create(Application);
smtp.IOHandler := io;
end;
smtp.UseTLS := utUseRequireTLS;
if PI_sUserName <> '' then begin
smtp.AuthType := satDefault;
end else begin
smtp.AuthType := satNone;
end;
smtp.HeloName := Split(PI_sUsername, 1, '#');
mail := TIdMessage.Create( Application );
try
mail.Clear;
mail.From.Address := PI_sSenderAddress;
mail.From.Text := PI_sSenderAddress;
mail.Subject := PI_sSubject;
mail.Recipients.EMailAddresses := ArrayToStr( PI_arrReceiverAddresses, ',' ); //!! only one
mail.CCList.EMailAddresses := ArrayToStr( PI_arrCCAddresses, ',' );
mail.BccList.EMailAddresses := ArrayToStr( PI_arrBCCAddresses, ',' );
mail.ReceiptRecipient.Text := '';
mail.Body.Add( PI_sMailText );
mail.Date := now;
if Length(PI_arrAttachments) > 0 then begin
SetLength(arrAttachments, Length(PI_arrAttachments));
for i := 0 to High(PI_arrAttachments) do begin
arrAttachments[i] := TIdAttachmentFile.Create(mail.MessageParts, PI_arrAttachments[i]);
end;
end;
try
smtp.ConnectTimeout := PI_nTimeoutSeconds * 1000;
smtp.Connect;
if smtp.Connected then begin
smtp.Send(mail);
end;
finally
smtp.disconnect;
if Length(arrAttachments) > 0 then begin
for i := 0 to High(arrAttachments) do begin
arrAttachments[i].Free;
end;
end;
end;
finally
mail.Free;
end;
finally
smtp.free;
if Assigned(io) then io.Free;
end;
end;
I call it like this:
SendMail(
'myaccount#web.de',
['receiver#web.de'],
[],
[],
'Subject',
'Text',
[],
'smtp.web.de',
'myaccount#web.de',
'mypassword',
True,
587
);
Can someone help?
EDIT: I changed to a googlemail account, but getting the same error. Currently, i call it like this:
I call it like this:
SendMail(
'myaccount#gmail.com',
['receiver#web.de'],
[],
[],
'Subject',
'Text',
[],
'smtp.gmail.com',
'myaccount#gmail.com',
'mypassword',
True,
587
);

`GNAT.SOCKETS.SOCKET_ERROR: [11]` Resource temporarily unavailable

I'm using this server to receive several data packages from a C++ UDP Client.
When i need a package i send a Request using a Client UDP to get the C++ Client send the package. When i do this process several times, i miss some packages and receive this error:
GNAT.SOCKETS.SOCKET_ERROR: [11] Resource temporarily unavailable
I think may cause because the client send the package before the server is listening, but I'm not sure. Is there any way to solve it?? If that is the problem, is there any way to ensure that my server is prepared before the client send the UDP message?
procedure RECEIVE_DATA (
DEST_UDP_PORT : In Integer;
SRC_UDP_PORT : In Integer;
WAIT_TIME : In DURATION;
MESSAGE_ADDRESS : Out System.Address;
WAIT_RESULT : Out Integer;
MESSAGE_SIZE : Out Integer
) is
Address : Sock_Addr_Type;
Socket : Socket_Type;
Channel : Stream_Access;
Receive_Timeout : constant Duration := WAIT_TIME;
Offset : Ada.Streams.Stream_Element_Count;
Data : Ada.Streams.Stream_Element_Array (1 .. 10000);
begin
Initialize (Process_Blocking_IO => False);
WAIT_RESULT := 0;
MESSAGE_SIZE := 0;
-- Create Socket
Create_Socket (Socket, Family_Inet, Socket_Datagram);
Set_Socket_Option (Socket => Socket,
Option => (Gnat.Sockets.Receive_Timeout, Timeout => Receive_Timeout));
--Bind Address
Address.Addr := Inet_Addr(DEFINE_IP_ADDR.IP_BOARD_ADDRESS);
Address.Port := Port_Type(DEST_UDP_PORT);
Bind_Socket (Socket, Address);
Channel := Stream (Socket, Address);
-- Receive Socket
Ada.Streams.Read (Channel.All, Data, Offset);
-- Close socket
Free (Channel);
Close_Socket (Socket);
WAIT_RESULT := 1;
MESSAGE_SIZE := Integer(Offset);
MESSAGE_ADDRESS := Data'Address;
Finalize;
exception when E : others =>
Ada.Text_IO.Put_Line
(Exception_Name (E) & ": " & Exception_Message (E));
WAIT_RESULT := 0;
Free (Channel);
Close_Socket (Socket);
Finalize;
end RECEIVE_DATA ;
Make the following change
Address.Addr := Inaddr_Any;
This is the address you are receiving from: not your address. Set your address when sending and any when receiving

How to Create an UDP client in Ada

I'm working on UDP communications using Ada. This code has to send some data to another host which is going to process it. I'm trying to send an initial message to start the communication, but it doesn't work. My client code is the following:
with GNAT.Sockets;
use GNAT.Sockets;
with Ada.Text_IO;
with Ada.Exceptions;
use Ada.Exceptions;
procedure Client_Send is
task Send is
entry Start;
entry Stop;
end Send;
task body Send is
Address : Sock_Addr_Type;
Socket : Socket_Type;
Channel : Stream_Access;
begin
accept Start;
-- See comments in Ping section for the first steps.
Address.Addr := Inet_Addr( "192.168.0.1" );
Address.Port := 7777;
Create_Socket (Socket,Family_Inet,Socket_Datagram);
Bind_Socket (Socket, Address);
Channel := Stream (Socket);
String'Output (Channel, "Hello world");
Free(Channel);
Ada.Text_IO.Put_Line ("Mesnaje Enviado");
Close_Socket (Socket);
accept Stop;
exception when E : others =>
Ada.Text_IO.Put_Line
(Exception_Name (E) & ": " & Exception_Message (E));
end Send;
begin
Initialize (Process_Blocking_IO => False);
Send.Start;
Send.Stop;
Finalize;
end Client_Send;
I'm using Wireshark to view the inbound traffic, but it doesn't receive anything.
Here is a simple UDP Client / Server in Ada with GNAT Sockets :
Client:
with Ada.Streams;
with Ada.Text_IO;
with GNAT.Sockets;
procedure UDP_Client is
use GNAT.Sockets;
Address : Sock_Addr_Type;
Socket : Socket_Type;
Data : constant Ada.Streams.Stream_Element_Array (1 .. 512) := (others => 42);
Last : Ada.Streams.Stream_Element_Offset;
begin
Address.Port := 50001;
Address.Addr := Inet_Addr ("127.0.0.1");
Create_Socket (Socket, Family_Inet, Socket_Datagram);
Send_Socket (Socket, Data, Last, Address);
Ada.Text_IO.Put_Line ("last :" & Last'Img);
end UDP_Client;
Server :
with Ada.Streams;
with Ada.Text_IO;
with GNAT.Sockets;
procedure UDP_Server is
use GNAT.Sockets;
Server : Socket_Type;
Address, From : Sock_Addr_Type;
Data : Ada.Streams.Stream_Element_Array (1 .. 512);
Last : Ada.Streams.Stream_Element_Offset;
Watchdog : Natural := 0;
begin
Create_Socket (Server, Family_Inet, Socket_Datagram);
Set_Socket_Option
(Server,
Socket_Level,
(Reuse_Address, True));
Set_Socket_Option
(Server,
Socket_Level,
(Receive_Timeout,
Timeout => 1.0));
Address.Addr := Any_Inet_Addr;
Address.Port := 50001;
Bind_Socket (Server, Address);
loop
begin
GNAT.Sockets.Receive_Socket (Server, Data, Last, From);
Ada.Text_IO.Put_Line ("last : " & Last'Img);
Ada.Text_IO.Put_Line ("from : " & Image (From.Addr));
exception
when Socket_Error =>
Watchdog := Watchdog + 1;
exit when Watchdog = 10;
end;
end loop;
end UDP_Server;
There are (at least) two problems with your program:
You are mixing up UDP and TCP. UDP is not a stream-oriented
protocol, so you shouldn't treat it as an Ada stream.
You aren't setting up a connection with another machine.
Here is an example of a program communicating over UDP: https://bitbucket.org/sparre/udp-chat