static int send_list_udp(struct socket_server *ss, struct socket *s, struct wb_list *list, struct socket_message *result) { while (list->head) { struct write_buffer * tmp = list->head; union sockaddr_all sa; socklen_t sasz = udp_socket_address(s, tmp->udp_address, &sa); int err = sendto(s->fd, tmp->ptr, tmp->sz, 0, &sa.s, sasz); if (err < 0) { switch(errno) { case EINTR: case AGAIN_WOULDBLOCK: return -1; } fprintf(stderr, "socket-server : udp (%d) sendto error %s.\n",s->id, strerror(errno)); return -1; /* // ignore udp sendto error result->opaque = s->opaque; result->id = s->id; result->ud = 0; result->data = NULL; return SOCKET_ERROR; */ } s->wb_size -= tmp->sz; list->head = tmp->next; write_buffer_free(ss,tmp); } list->tail = NULL; return -1; }
static int send_list_tcp(struct socket_server *ss, struct socket *s, struct wb_list *list, struct socket_message *result) { while (list->head) { struct write_buffer * tmp = list->head; for (;;) { int sz = write(s->fd, tmp->ptr, tmp->sz); if (sz < 0) { switch(errno) { case EINTR: continue; case EAGAIN: return -1; } force_close(ss,s, result); return SOCKET_CLOSE; } s->wb_size -= sz; if (sz != tmp->sz) { tmp->ptr += sz; tmp->sz -= sz; return -1; } break; } list->head = tmp->next; write_buffer_free(ss,tmp); } list->tail = NULL; return -1; }
// 清空写缓冲区,并释放内存空间 static void free_wb_list(struct socket_server *ss, struct wb_list *list) { struct write_buffer *wb = list->head; while (wb) { struct write_buffer *tmp = wb; wb = wb->next; write_buffer_free(ss, tmp); } list->head = NULL; list->tail = NULL; }
// 发送tcp数据 // 正常返回 -1 // 失败返回 SOCKET_CLOSE static int send_list_tcp(struct socket_server *ss, struct socket *s, struct wb_list *list, struct socket_message *result) { while (list->head) { struct write_buffer * tmp = list->head; for (;;) { // 往套接字写入数据 int sz = write(s->fd, tmp->ptr, tmp->sz); if (sz < 0) { switch(errno) { case EINTR: // 信用中断,循环等待 continue; case AGAIN_WOULDBLOCK: // 写缓冲区满,直接返回 return -1; } // 关闭socket force_close(ss,s, result); return SOCKET_CLOSE; } s->wb_size -= sz; if (sz != tmp->sz) { // 如果缓冲区数据没有发送完,直接返回-1 // tmp缓冲区仍然在缓冲区链表中,等待下一次发送 tmp->ptr += sz; tmp->sz -= sz; return -1; } break; } // head指针偏移到tmp下一个缓冲区 list->head = tmp->next; // 释放tmp缓冲区 write_buffer_free(ss,tmp); } list->tail = NULL; return -1; }