PHP Sockets

Posted on 2010-08-25
Medium Priority
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 working...it 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)
Ransomware: The New Cyber Threat & How to Stop It

This infographic explains ransomware, type of malware that blocks access to your files or your systems and holds them hostage until a ransom is paid. It also examines the different types of ransomware and explains what you can do to thwart this sinister online threat.  


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

Get real performance insights from real users

Key features:
- Total Pages Views and Load times
- Top Pages Viewed and Load Times
- Real Time Site Page Build Performance
- Users’ Browser and Platform Performance
- Geographic User Breakdown
- And more

Question has a verified solution.

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

This article discusses how to implement server side field validation and display customized error messages to the client.
This article outlines some of the reasons why an email message gets flagged as spam on a recipient's end.
The video tutorial explains the basics of the Exchange server Database Availability groups. The components of this video include: 1. Automatic Failover 2. Failover Clustering 3. Active Manager
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
Suggested Courses

777 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