PHP Sockets

Posted on 2010-08-25
Last Modified: 2012-06-27

I have reached about the end of my patience with this guys so I am hoping someone could let me know whats going on.

I think I know what the problem maybe but have no idea how to solve it.

If I can get away from showing the public the code I would appricate it as it's took me month's to develop to get this far.

Basicly I am using stream_socket_client in non blocking mode to connect to multiple smtp servers at the same time using stream_select.

Everything is working perfectly and I can achieve 600k + emails an hour to our opted in members list with one script so I am pritty happy about that.

The problem is when I try to use a large email copy i.e 200+ html lines things stop seams to be a limit on fwrite and quite possibly fwrite is simply not sending all the lines to the smtp server to finish the connection.

Does any one know of any limits or to get around it using sockets/fwrite...I've tried sending a series of different fwrites but the moment I introduce too much combined html it fails.

Thanks so much for your help!

Question by:jayipeak
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 4
LVL 11

Expert Comment

ID: 33520550
jayipeak>>The problem is when I try to use a large email copy i.e 200+ html lines things stop working

Do you get an error message that you can share? Or does php just hang/freeze?

Author Comment

ID: 33520574
It's prrity hard to explain basicly SMTP looks for \r\n.\r\n at the end of a email message to know when it's reached the end, because of the write buffer which i am guessing is (8KB?) it never reaches that line so the connection just hangs.

I've tried stream_set_write_buffer but that doesn't seam to have any effect.
LVL 11

Expert Comment

ID: 33521378
Is it possible to take either a manual or low-level packet approach to this? For example, maybe you could serialize or break the message into segments where each segment has some identifier that when arriving at SMTP can be rebuilt into a usable string.

It's hard to troubleshoot this without seeing any code - but maybe you could provide a tech-map of start to finish what's involved, and what interfaces/technologies are used along the way (i.e. what server OS, what scripts/externals/libs, what smtp software, etc)
Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)


Expert Comment

ID: 33522102
you might try using MULTIPART email

Author Comment

ID: 33523064
Ok Guys, just to update you.

I now know 100% that it's todo with fwrite/buffer...basicly by default when using fwrite it uses a 8KB buffer, because I setup the socket as a stream with stream_socket_client I can't seam to use stream_set_write_buffer which is werid it seams to have no affect...if I pop the connection into blocking mode before writing it works perfectly as there is no need for buffering.

the email I am sending is 40KB hense the issues, it's a shame the SMTP protocol doesn't allow you to send your email message in batches either way I need to increase fwrite's buffer.
LVL 11

Expert Comment

ID: 33524682
jayipeak>>I need to increase fwrite's buffer.

Or as I mentioned, considering breaking the email into segments - is this a possibility? You could do all the segmenting into 8kb 'packets' in your php script prior to sending, but since you didn't really let us know what's going on the other end - I can't shed much light on what options you have to reconstruct them.

Author Comment

ID: 33524707
Hi level9wizard,

Thanks for your feedback.

The script as I mentioned is connecting to a SMTP servers and mailing out to our members, so we have no control over the other side! Would be a lot easier if that was the case!

Thanks Again

Author Comment

ID: 33524747
If there was a way to find out there is nothing left in the buffer after a fwrite call so I can call fwrite again with the remaining part of the message then great, although the best way would be to find a way of increasing the buffer before doing a fwrite.

Author Comment

ID: 33524760
And btw the only thing I could find in regards to the SMTP protocol intending to send it in parts would be a extension called `CHUNKING` but not all mail servers support it :-(

Accepted Solution

jayipeak earned 0 total points
ID: 33525537
Well Guys I've found my own solution eventually...

fwrite returns the number of bytes written into the buffer (when i non blocking mode) I then keep a track of how much I've already written then come back to that socket after it's had a little time to send some data over.

Simple! but never seams simple when your pulling your hair out!

Here is a example:
while ($written_count < strlen($towrite))
       $temp = substr($towrite, $written, strlen($towrite)-$written_count);
       $actual_written = fwrite($w, $temp);
       $written_count += $actual_written;
       // DO SOMETHING ELSE WHILE WAITING or use `usleep(500)`

Open in new window

LVL 11

Expert Comment

ID: 33530633
jayipeak >> so your breaking this into several chunks? That's basically what I said above -code.

Author Comment

ID: 33530667
Hi level9wizzard,

Basicly yeah, but because smtp doesn't accept you to send it via chunks there was no way of knowing how much was sent as the remote server only replies back when the full message has been sent...thankfully the return value of fwrite posed a idea of counting how many bytes went into the buffer so it could be handled at our side.


Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Utilizing an array to gracefully append to a list of EmailAddresses
As cyber crime continues to grow in both numbers and sophistication, a troubling trend of optimization has emerged over the last year.
To show how to create a transport rule in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.: First we need to log into the Exchange Admin Center. Navigate to the Mail Flow >> Rules tab.:  To cr…
To show how to generate a certificate request in Exchange 2013. We show this process by using the Exchange Admin Center. Log into Exchange Admin Center.:  First we need to log into the Exchange Admin Center. Navigate to the Servers >> Certificates…

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question