Skip to content

一次tcp错误排查

Posted on:March 22, 2021 at 01:13 PM

一个使用php的workman的代码抛出了这样的异常

fwrite(): send of 157 bytes failed with errno=11 Resource temporarily unavailable

socket是使用了noblocking的,结果有一个这个错误,结果发现是已经修复了不抛异常了,但是在我的php5.6的版本还是旧的代码,所以还是会抛这个异常,所以排查了一天,不是bug 最新的修改

https://github.com/php/php-src/pull/5026/files
	didwrite = send(sock->socket, buf, XP_SOCK_BUF_SIZE(count), (sock->is_blocked && ptimeout) ? MSG_DONTWAIT : 0);

	if (didwrite <= 0) {
		char *estr;
		int err = php_socket_errno();
		if (err == EWOULDBLOCK || err == EAGAIN) {
			if (sock->is_blocked) {
				int retval;

				sock->timeout_event = 0;

				do {
					retval = php_pollfd_for(sock->socket, POLLOUT, ptimeout);

					if (retval == 0) {
						sock->timeout_event = 1;
						break;
					}

					if (retval > 0) {
						/* writable now; retry */
						goto retry;
					}

					err = php_socket_errno();
				} while (err == EINTR);
			} else {
				/* EWOULDBLOCK/EAGAIN is not an error for a non-blocking stream.
				 * Report zero byte write instead. */
				return 0;
			}
		}

		estr = php_socket_strerror(err, NULL, 0);
		php_error_docref(NULL, E_NOTICE, "Send of " ZEND_LONG_FMT " bytes failed with errno=%d %s",
				(zend_long)count, err, estr);
		efree(estr);
	}

	if (didwrite > 0) {
		php_stream_notify_progress_increment(PHP_STREAM_CONTEXT(stream), didwrite, 0);
	}

	return didwrite;
}