生活随笔
收集整理的這篇文章主要介紹了
Linux网络编程(四)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?
????TCP雖然可以實(shí)現(xiàn)?IO非阻塞操作,但在實(shí)際應(yīng)用時(shí)會(huì)對(duì)資源是否準(zhǔn)備完畢進(jìn)行循環(huán)測試,增加了不必要的CPU占用。
?
??? 為了解決這種問題,應(yīng)用多路復(fù)用的知識(shí),select()監(jiān)聽信號(hào)。相關(guān)知識(shí)可以參考 linux文件讀寫 文件鎖 select poll 。
?
???????? 服務(wù)端:
?
[cpp] view plain copy print ?
#include?<sys/types.h>??#include?<sys/socket.h>??#include?<stdio.h>??#include?<stdlib.h>??#include?<string.h>??#include?<sys/time.h>??#include?<sys/ioctl.h>??#include?<unistd.h>??#include?<netinet/in.h>????#define?PORT????????????????4321??#define?MAX_QUE_CONN_NM?????????5??#define?MAX_SOCK_FD?????????FD_SETSIZE??#define?BUFFER_SIZE?????????1024????int?main(){??????struct?sockaddr_in?server_sockaddr,?client_sockaddr;??????int?sin_size,?count;??????fd_set?inset,?tmp_inset;??????int?sockfd,?client_fd,?fd;??????char?buf[BUFFER_SIZE];????????if?((sockfd?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1){??????????perror(”socket”);??????????exit(1);??????}????????server_sockaddr.sin_family?=?AF_INET;??????server_sockaddr.sin_port?=?htons(PORT);??????server_sockaddr.sin_addr.s_addr?=?INADDR_ANY;??????bzero(&(server_sockaddr.sin_zero),?8);????????int?i?=?1;????????????setsockopt(sockfd,?SOL_SOCKET,?SO_REUSEADDR,?&i,?sizeof(i));??????if?(bind(sockfd,?(struct?sockaddr?*)&server_sockaddr,?sizeof(struct?sockaddr))?==?-1){??????????perror(”bind”);??????????exit(1);??????}????????if(listen(sockfd,?MAX_QUE_CONN_NM)?==?-1){??????????perror(”listen”);??????????exit(1);??????}??????printf(”listening….\n”);????????????FD_ZERO(&inset);??????????FD_SET(sockfd,?&inset);????????while(1){??????????tmp_inset?=?inset;???????????????sin_size=sizeof(struct?sockaddr_in);??????????memset(buf,?0,?sizeof(buf));??????????printf(”run?while…\n”);????????????????????if?(!(select(MAX_SOCK_FD,?&tmp_inset,?NULL,?NULL,?NULL)?>?0)){????????????????perror(”select”);??????????????close(sockfd);??????????????exit(1);??????????}??????????printf(”run?for…\n”);??????????for?(fd?=?0;?fd?<?MAX_SOCK_FD;?fd++){??????????????if?(FD_ISSET(fd,?&tmp_inset)?>?0)?{??????????????????printf(”fd?is?%d?,socket?is?%d\n”,fd,sockfd);??????????????????if?(fd?==?sockfd){???????????????????????????????if?((client_fd?=?accept(sockfd,?(struct?sockaddr?*)&client_sockaddr,?&sin_size))==?-1){??????????????????????????perror(”accept”);??????????????????????????exit(1);??????????????????????}????????????????????????FD_SET(client_fd,?&inset);??????????????????????printf(”New?connection?from?%d(socket)\n”,?client_fd);??????????????????}else{??????????????????????if?((count?=?recv(fd,?buf,?BUFFER_SIZE,?0))?>?0){??????????????????????????printf(”Received?a?message?from?%d:?%s\n”,?fd,?buf);??????????????????????}else{??????????????????????????close(fd);??????????????????????????FD_CLR(fd,?&inset);??????????????????????????printf(”Client?%d(socket)?has?left\n”,?fd);??????????????????????}??????????????????}??????????????}???????????}???????}?????????close(sockfd);??????exit(0);??}??
#include <sys/types.h>
include <sys/socket.h>
include <stdio.h>
include <stdlib.h>
include <string.h>
include <sys/time.h>
include <sys/ioctl.h>
include <unistd.h>
include <netinet/in.h>
define PORT 4321
define MAX_QUE_CONN_NM 5
define MAX_SOCK_FD FD_SETSIZE
define BUFFER_SIZE 1024
int main(){
struct sockaddr_in server_sockaddr, client_sockaddr;
int sin_size, count;
fd_set inset, tmp_inset;
int sockfd, client_fd, fd;
char buf[BUFFER_SIZE];
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("socket");exit(1);
}server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(PORT);
server_sockaddr.sin_addr.s_addr = INADDR_ANY;
bzero(&(server_sockaddr.sin_zero), 8);int i = 1;
//設(shè)置socket的屬性
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
if (bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1){perror("bind");exit(1);
}if(listen(sockfd, MAX_QUE_CONN_NM) == -1){perror("listen");exit(1);
}
printf("listening....\n");
//清空select集合
FD_ZERO(&inset);
//將要檢測的文件符加入 FD_SET(sockfd, &inset);
while(1){tmp_inset = inset; sin_size=sizeof(struct sockaddr_in);memset(buf, 0, sizeof(buf));printf("run while...\n");//程序在此阻塞,select返回一個(gè)文件符,并將其他文件符清空if (!(select(MAX_SOCK_FD, &tmp_inset, NULL, NULL, NULL) > 0)){ perror("select");close(sockfd);exit(1);}printf("run for...\n");for (fd = 0; fd < MAX_SOCK_FD; fd++){if (FD_ISSET(fd, &tmp_inset) > 0) {printf("fd is %d ,socket is %d\n",fd,sockfd);if (fd == sockfd){ if ((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size))== -1){perror("accept");exit(1);}FD_SET(client_fd, &inset);printf("New connection from %d(socket)\n", client_fd);}else{if ((count = recv(fd, buf, BUFFER_SIZE, 0)) > 0){printf("Received a message from %d: %s\n", fd, buf);}else{close(fd);FD_CLR(fd, &inset);printf("Client %d(socket) has left\n", fd);}}} /* end of if FD_ISSET*/} /* end of for fd*/
} /* end if while while*/close(sockfd);
exit(0);
}
?
???? 客戶端:
?
[cpp] view plain copy print ?
<span?style=“font-size:18px;”>#include?<sys/types.h>??#include?<sys/socket.h>??#include?<stdio.h>??#include?<stdlib.h>??#include?<string.h>??#include?<sys/ioctl.h>??#include?<unistd.h>??#include?<netdb.h>??#include?<netinet/in.h>????#define?PORT????4321??#define?BUFFER_SIZE?1024????int?main(int?argc,?char?*argv[]){??????int?sockfd,?sendbytes;??????char?buf[BUFFER_SIZE];??????struct?hostent?*host;??????struct?sockaddr_in?serv_addr;????????if(argc?<?3){??????????fprintf(stderr,”USAGE:?./client?Hostname(or?ip?address)?Text\n”);??????????exit(1);??????}????????if?((host?=?gethostbyname(argv[1]))?==?NULL){??????????perror(”gethostbyname”);??????????exit(1);??????}????????memset(buf,?0,?sizeof(buf));??????sprintf(buf,?”%s”,?argv[2]);????????if?((sockfd?=?socket(AF_INET,SOCK_STREAM,0))?==?-1){??????????perror(”socket”);??????????exit(1);??????}????????serv_addr.sin_family?=?AF_INET;??????serv_addr.sin_port?=?htons(PORT);??????serv_addr.sin_addr?=?*((struct?in_addr?*)host->h_addr);??????bzero(&(serv_addr.sin_zero),?8);????????if(connect(sockfd,(struct?sockaddr?*)&serv_addr,?sizeof(struct?sockaddr))==?-1){??????????perror(”connect”);??????????exit(1);??????}????????if?((sendbytes?=?send(sockfd,?buf,?strlen(buf),?0))?==?-1){??????????perror(”send”);??????????exit(1);??????}??????sleep(30);??????close(sockfd);??????exit(0);??}??</span>??
#include <sys/types.h>
include <sys/socket.h>
include <stdio.h>
include <stdlib.h>
include <string.h>
include <sys/ioctl.h>
include <unistd.h>
include <netdb.h>
include <netinet/in.h>
define PORT 4321
define BUFFER_SIZE 1024
int main(int argc, char *argv[]){
int sockfd, sendbytes;
char buf[BUFFER_SIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if(argc < 3){fprintf(stderr,"USAGE: ./client Hostname(or ip address) Text\n");exit(1);
}if ((host = gethostbyname(argv[1])) == NULL){perror("gethostbyname");exit(1);
}memset(buf, 0, sizeof(buf));
sprintf(buf, "%s", argv[2]);if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){perror("socket");exit(1);
}serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero), 8);if(connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(struct sockaddr))== -1){perror("connect");exit(1);
}if ((sendbytes = send(sockfd, buf, strlen(buf), 0)) == -1){perror("send");exit(1);
}
sleep(30);
close(sockfd);
exit(0);
}
?
?
?
本篇博客出自? 阿修羅道,轉(zhuǎn)載出處:http://blog.csdn.net/fansongy/article/details/6901322
總結(jié)
以上是生活随笔為你收集整理的Linux网络编程(四)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。