Linux下socket有select、poll、epoll和AIO等方式,其中,前三種爲同步方式。linux
有不少種方法能夠設置socket爲非阻塞模式,經常使用的是使用fcntl(sockfd, F_SETFL, O_NONBLOCK);segmentfault
在阻塞模式下,能夠經過setsockopt來設置(讀/寫)超時,connect也能夠用setsockopt來設置,與寫參數一致:異步
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO,&timeo, len);
connect的超時通常是nonblocking+select。socket
同步、異步與阻塞、非阻塞的區別async
Linux IO模式及 select、poll、epoll詳解ide
建立socket -> bind -> listen -> accept -> send/recv -> closespa
代碼摘自http://blog.csdn.net/shallnet/article/details/17734919,後同.net
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <arpa/inet.h> #include <netinet/in.h> #include "server.h" #include "ly_debug.h" void accept_handle(int connfd, struct sockaddr_in peeraddr); int main(int argc, const char *argv[]) { int sockfd, connfd; struct sockaddr_in seraddr, peeraddr; socklen_t addrlen; COMPILE_TIME_PRINT; if (argc != 2) { printf("Usage: %s <port>\n", argv[0]); return -1; } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { LY_ERR("socket: %s\n", strerror(errno)); return -1; } seraddr.sin_family = AF_INET; seraddr.sin_port = ntohs(atoi(argv[1])); seraddr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sockfd, (struct sockaddr *)&seraddr, sizeof(struct sockaddr))) { LY_ERR("bind: %s\n", strerror(errno)); return -1; } if (listen(sockfd, MAX_CONN) < 0) { LY_ERR("listen: %s\n", strerror(errno)); return -1; } addrlen = sizeof(struct sockaddr); for (;;) { connfd = accept(sockfd, (struct sockaddr *)(&peeraddr), &addrlen); if (connfd < 0) { LY_ERR("accept: %s\n", strerror(errno)); continue; } accept_handle(connfd, peeraddr); } return 0; } void accept_handle(int connfd, struct sockaddr_in peeraddr) { char buf[32] = "Hello, welcome to server!"; LY_IFO("Receive request from %s, port %d\n", inet_ntop(AF_INET, &peeraddr.sin_addr, buf, sizeof(buf)), ntohs(peeraddr.sin_port)); //sleep(10); if (send(connfd, buf, sizeof(buf), 0) < 0) { LY_ERR("send: %s\n", strerror(errno)); return; } close(connfd); LY_IFO("send info: %s\n", buf); }
建立socket -> connect -> send/recv->closedebug
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <stdlib.h> #include <netinet/in.h> #include <arpa/inet.h> #include "ly_debug.h" int main(int argc, const char *argv[]) { int sockfd; struct sockaddr_in seraddr; char recvbuf[32]; COMPILE_TIME_PRINT; if (argc != 3) { LY_PRT("Usage: %s <ip> <port>\n", argv[0]); return -1; } if (inet_pton(AF_INET, argv[1], &seraddr.sin_addr) < 0) { LY_ERR("inet_pton: %s\n", strerror(errno)); return -1; } sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { LY_ERR("socket: %s\n", strerror(errno)); return -1; } seraddr.sin_family = AF_INET; seraddr.sin_port = htons(atoi(argv[2])); if (connect(sockfd, (struct sockaddr *)(&seraddr), sizeof(struct sockaddr)) < 0) { LY_ERR("connect: %s\n", strerror(errno)); return -1; } if (recv(sockfd, recvbuf, sizeof(recvbuf), 0) < 0) { LY_ERR("recv: %s\n", strerror(errno)); return -1; } LY_PRT("From server: %s\n", recvbuf); close(sockfd); return 0; }