⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_io.c

📁 类似apache2.0的多线程技术,目的在于解决网络服务器在并发客户数很大的情况下服务器进程分配(fork)而带来的效率瓶颈.
💻 C
字号:
#include <stdlib.h>#include <string.h>#include <unistd.h>#include "network.h"#include "s_io.h"/* * 打开套接字流指针。 */struct s_stream *s_open(int fd){    struct s_stream *sp;     sp = (struct s_stream *)malloc(sizeof(struct s_stream));    if (!sp)        return NULL;    sp->fd = fd;    sp->ch = '\0';    sp->num = 0;    return sp;}/* * 关闭套接字流指针。 */int s_close(struct s_stream *sp){    if (sp) {        close(sp->fd);        free(sp);    }    return 0;}/* * 返回读取nmemb个数。 */int s_read(void *ptr, int size, int nmemb, struct s_stream *sp){    int i, ret, nleft = size;    if (1 == sp->num) {        *(char *)ptr = sp->ch;         nleft--;        sp->num = 0;        sp->ch = '\0';    }    for (i = 0; i < nmemb; i++) {        while (nleft) {            ret = t_read(sp->fd, READ_TIMEOUT, ptr + (i + 1) * size - nleft, size);            if (-1 == ret)                return i;            nleft -= ret;        }    }    return nmemb;}/* * 返回写入nmemb个数。 */int s_write(void *ptr, int size, int nmemb, struct s_stream *sp){    int i, ret, nleft = size;    for (i = 0; i < nmemb; i++) {        while (nleft) {            ret = t_write(sp->fd, WRITE_TIMEOUT, ptr + (i + 1) * size - nleft, size);            if (-1 == ret)                return i;            nleft -= ret;        }    }    return nmemb;}int s_putc(char c, struct s_stream *sp){    int ret;    ret = t_write(sp->fd, WRITE_TIMEOUT, &c, 1);    if (-1 == ret)        return -1;    return 0;}/* * 返回写入字节数。 */int s_puts(char *s, struct s_stream *sp){    int ret;    int nleft, len;    nleft = len = strlen(s);    while (nleft) {         ret = t_write(sp->fd, WRITE_TIMEOUT, s, len);        if (-1 == ret)            break;        nleft -= ret;    }    return len - nleft;}/* * 读取一字符。 */char s_getc(struct s_stream *sp){    char ch;    int ret;    if (1 == sp->num) {        ch = sp->ch;         sp->num = 0;        sp->ch = '\0';        return ch;    }    ret = t_read(sp->fd, READ_TIMEOUT, &ch, 1);    if (-1 == ret)        return -1;    return ch;}/* * 读取直到\r\n 或 s被填满 或套接字关闭。 */int s_gets(char *s, int size, struct s_stream *sp){    int ret;    int i, unchar = 0;    char ch;    memset(s, 0, size);    if (1 == sp->num) {        s[0] = sp->ch;        unchar++;        sp->num = 0;        sp->ch = '\0';    }    for (i = unchar; i < size - 2; i++) {        ret = t_read(sp->fd, READ_TIMEOUT, &ch, 1);        if (-1 == ret)            return -1;        if ('\r' == ch || '\n' == ch) {            // 此时应该非阻塞读,因为对方可能关闭,可能阻塞。            fd_set_noblock(sp->fd);            ret = readn(sp->fd, &ch, 1);            if (-1 == ret) {     // 读错误,无数据。                break;            } else if (0 == ret) {  // 套接字被关闭。                break;            } else {    // 正确读回。                if ('\r' != ch && '\n' != ch) {                    s_ungetc(ch, sp);                } else {                    break;                }            }            fd_set_block(sp->fd);        }        s[i] = ch;    }    return 0;}int s_ungetc(char c, struct s_stream *sp){    sp->ch = c;    sp->num = 1;    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -