IO非阻塞操作
sock的方法不一定非得是阻塞的,也可以非阻塞的操作。有兩種方法分別為設定fcntl 和設定相應函數的參數。
服務端:
#include <sys/socket.h>#include <stdio.h>#include <string.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#define BUFSIZE 128int main(int argc,char *argv[]){ int server_sockfd, client_sockfd; int server_len, client_len; struct sockaddr_in server_address; struct sockaddr_in client_address; int i,byte; char char_send[BUFSIZE]; server_sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&server_address, sizeof(server_address)); server_address.sin_family = AF_INET; server_address.sin_port = htons(7838); server_address.sin_addr.s_addr = INADDR_ANY; server_len = sizeof(server_address); if ((bind(server_sockfd, (struct sockaddr *)&server_address, server_len))== -1) { perror("bind"); exit(EXIT_FAILURE); } listen(server_sockfd, 5); printf("server waiting for connect\n"); client_len = sizeof(client_address); client_sockfd = accept(server_sockfd,(struct sockaddr *)&client_address, (socklen_t *)&client_len); for(i=0;i<5;i++){ memset(char_send,'\0',BUFSIZE); printf("input message to send:"); fgets(char_send,BUFSIZE,stdin); if((byte=send(client_sockfd,char_send,strlen(char_send),0))==-1){ perror("send"); exit(EXIT_FAILURE); } memset(char_send,'\0',BUFSIZE); //最後一個參數為非阻塞的設定 byte = recv(client_sockfd, char_send, BUFSIZE,MSG_DONTWAIT); if(byte > 0){ printf("get %d message:%s", byte, char_send); byte=0; }else if(byte<0){ if(errno==EAGAIN){ errno=0; continue; }else{ perror("recv"); exit(EXIT_FAILURE); } } } shutdown(client_sockfd,2); shutdown(server_sockfd,2);}
用戶端:
#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/socket.h>#include <resolv.h>#include <stdlib.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include <fcntl.h>#define MAXBUF 128int main(int argc, char **argv){ int sockfd, ret, i; struct sockaddr_in dest, mine; char buffer[MAXBUF + 1]; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("Socket"); exit(EXIT_FAILURE); } bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(7838); if(argc<2){ printf("Usage: %s <dest ip> <src ip>",argv[0]); exit(1); } if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0){ perror(argv[1]); exit(1); } bzero(&mine, sizeof(mine)); mine.sin_family = AF_INET; mine.sin_port = htons(7839); if (inet_aton(argv[2], (struct in_addr *) &mine.sin_addr.s_addr) == 0){ perror(argv[2]); exit(EXIT_FAILURE); } if (bind(sockfd, (struct sockaddr *) &mine, sizeof(struct sockaddr)) == -1){ perror(argv[3]); exit(EXIT_FAILURE); } printf("will connect!\n"); if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) { perror("Connect "); exit(EXIT_FAILURE); } //設定sock串連的非阻塞 if(fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) { perror("fcntl"); exit(EXIT_FAILURE); } while(1){ bzero(buffer, MAXBUF + 1); //因為在socket中設定過,所以就不用再設定了 ret = recv(sockfd, buffer, MAXBUF, 0); if(ret > 0){ printf("get %d message:%s", ret, buffer); ret=0; }else if(ret < 0) { if(errno == EAGAIN) { errno=0; continue; }else{ perror("recv"); exit(EXIT_FAILURE); } } memset( buffer,'\0',MAXBUF+1); printf("input message to send:"); fgets( buffer,MAXBUF,stdin); if((ret=send(sockfd,buffer,strlen(buffer),0))==-1){ perror("send"); exit(EXIT_FAILURE); } } close(sockfd); return 0;}
本篇部落格出自 阿修羅道,轉載請註明出處:http://blog.csdn.net/fansongy/article/details/6898577