http://blog.csdn.net/shanshanpt/article/details/7383400
server.c
-
// gcc server.c -o server
-
// indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *
-
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <sys/types.h>
-
#include <errno.h>
-
#include <sys/socket.h>
-
#include <netinet/in.h> /* socket类定义需要 */
-
#include <sys/epoll.h> /* epoll头文件 */
-
#include <fcntl.h> /* nonblocking需要 */
-
#include <sys/resource.h> /* 设置最大的连接数需要setrlimit */
-
-
#define MAXEPOLL 10000 /* 对于服务器来说,这个值可以很大的! */
-
#define MAXLINE 1024
-
#define PORT 6000
-
#define MAXBACK 1000
-
-
//!> 设置非阻塞
-
//!>
-
int setnonblocking(int fd)
-
{
-
if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFD, 0) | O_NONBLOCK) == -1) {
-
printf("Set blocking error : %d\n", errno);
-
return -1;
-
}
-
return 0;
-
}
-
-
int main(int argc, char **argv)
-
{
-
int listen_fd;
-
int conn_fd;
-
int epoll_fd;
-
int nread;
-
int cur_fds; //!> 当前已经存在的数量
-
int wait_fds; //!> epoll_wait 的返回值
-
int i;
-
struct sockaddr_in servaddr;
-
struct sockaddr_in cliaddr;
-
struct epoll_event ev;
-
struct epoll_event evs[MAXEPOLL];
-
struct rlimit rlt; //!> 设置连接数所需
-
char buf[MAXLINE];
-
socklen_t len = sizeof(struct sockaddr_in);
-
-
//!> 设置每个进程允许打开的最大文件数
-
//!> 每个主机是不一样的哦,一般服务器应该很大吧!
-
//!>
-
rlt.rlim_max = rlt.rlim_cur = MAXEPOLL;
-
if (setrlimit(RLIMIT_NOFILE, &rlt) == -1) {
-
printf("Setrlimit Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
//!> server 套接口
-
//!>
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
-
servaddr.sin_port = htons(PORT);
-
-
//!> 建立套接字
-
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-
printf("Socket Error...\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
//!> 设置非阻塞模式
-
//!>
-
if (setnonblocking(listen_fd) == -1) {
-
printf("Setnonblocking Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
//!> 绑定
-
//!>
-
if (bind(listen_fd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) == -1) {
-
printf("Bind Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
//!> 监听
-
//!>
-
if (listen(listen_fd, MAXBACK) == -1) {
-
printf("Listen Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
//!> 创建epoll
-
//!>
-
epoll_fd = epoll_create(MAXEPOLL); //!> create
-
ev.events = EPOLLIN | EPOLLET; //!> accept
-
ev.data.fd = listen_fd; //!> 将listen_fd 加入
-
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &ev) < 0) {
-
printf("Epoll Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
cur_fds = 1;
-
-
while (1) {
-
if ((wait_fds = epoll_wait(epoll_fd, evs, cur_fds, -1)) == -1) {
-
printf("Epoll Wait Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
-
for (i = 0; i < wait_fds; i++) {
-
if (evs[i].data.fd == listen_fd && cur_fds < MAXEPOLL)
-
//!> if是监听端口有事
-
{
-
if ((conn_fd = accept(listen_fd, (struct sockaddr *)&cliaddr, &len)) == -1) {
-
printf("Accept Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
-
printf("Server get from client !\n" /*, inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port */ );
-
-
ev.events = EPOLLIN | EPOLLET; //!> accept
-
ev.data.fd = conn_fd; //!> 将conn_fd 加入
-
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, conn_fd, &ev) < 0) {
-
printf("Epoll Error : %d\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
++cur_fds;
-
continue;
-
}
-
//!> 下面处理数据
-
//!>
-
nread = read(evs[i].data.fd, buf, sizeof(buf));
-
if (nread <= 0) //!> 结束后者出错
-
{
-
close(evs[i].data.fd);
-
epoll_ctl(epoll_fd, EPOLL_CTL_DEL, evs[i].data.fd, &ev); //!> 删除计入的fd
-
--cur_fds; //!> 减少一个呗!
-
continue;
-
}
-
-
write(evs[i].data.fd, buf, nread); //!> 回写
-
-
}
-
}
-
-
close(listen_fd);
-
return 0;
-
}
client.c
-
// gcc client.c -o client
-
// indent -npro -kr -i8 -ts8 -sob -l280 -ss -ncs -cp1 *
-
-
#include <stdio.h>
-
#include <unistd.h>
-
#include <stdlib.h>
-
#include <string.h>
-
#include <errno.h>
-
#include <netinet/in.h>
-
#include <sys/types.h>
-
#include <sys/socket.h>
-
#include <arpa/inet.h>
-
#include <sys/select.h>
-
-
#define MAXLINE 1024
-
#define SERV_PORT 6000
-
-
//!> 注意输入是由stdin,接受是由server发送过来
-
//!> 所以在client端也是需要select进行处理的
-
void send_and_recv(int connfd)
-
{
-
FILE *fp = stdin;
-
int lens;
-
char send[MAXLINE];
-
char recv[MAXLINE];
-
fd_set rset;
-
FD_ZERO(&rset);
-
int maxfd = (fileno(fp) > connfd ? fileno(fp) : connfd + 1);
-
//!> 输入和输出的最大值
-
int n;
-
-
while (1) {
-
FD_SET(fileno(fp), &rset);
-
FD_SET(connfd, &rset); //!> 注意不要把rset看作是简单的一个变量
-
//!> 注意它其实是可以包含一组套接字的哦,
-
//!> 相当于是封装的数组!每次都要是新的哦!
-
-
if (select(maxfd, &rset, NULL, NULL, NULL) == -1) {
-
printf("Client Select Error..\n");
-
exit(EXIT_FAILURE);
-
}
-
//!> if 连接口有信息
-
if (FD_ISSET(connfd, &rset)) //!> if 连接端口有信息
-
{
-
printf("client get from server ...\n");
-
memset(recv, 0, sizeof(recv));
-
n = read(connfd, recv, MAXLINE);
-
if (n == 0) {
-
printf("Recv ok...\n");
-
break;
-
} else if (n == -1) {
-
printf("Recv error...\n");
-
break;
-
} else {
-
lens = strlen(recv);
-
recv[lens] = '\0';
-
//!> 写到stdout
-
write(STDOUT_FILENO, recv, MAXLINE);
-
printf("\n");
-
}
-
-
}
-
//!> if 有stdin输入
-
if (FD_ISSET(fileno(fp), &rset)) //!> if 有输入
-
{
-
//!> printf("client stdin ...\n");
-
-
memset(send, 0, sizeof(send));
-
if (fgets(send, MAXLINE, fp) == NULL) {
-
printf("End...\n");
-
exit(EXIT_FAILURE);
-
} else {
-
//!>if( str )
-
lens = strlen(send);
-
send[lens - 1] = '\0'; //!> 减一的原因是不要回车字符
-
//!> 经验值:这一步非常重要的哦!!!!!!!!
-
if (strcmp(send, "q") == 0) {
-
printf("Bye..\n");
-
return;
-
}
-
-
printf("Client send : %s\n", send);
-
write(connfd, send, strlen(send));
-
}
-
}
-
-
}
-
-
}
-
-
int main(int argc, char **argv)
-
{
-
//!> char * SERV_IP = "10.30.97.188";
-
char buf[MAXLINE];
-
int connfd;
-
struct sockaddr_in servaddr;
-
-
if (argc != 2) {
-
printf("Input server ip !\n");
-
exit(EXIT_FAILURE);
-
}
-
//!> 建立套接字
-
if ((connfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
-
printf("Socket Error...\n", errno);
-
exit(EXIT_FAILURE);
-
}
-
//!> 套接字信息
-
bzero(&servaddr, sizeof(servaddr));
-
servaddr.sin_family = AF_INET;
-
servaddr.sin_port = htons(SERV_PORT);
-
inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
-
-
//!> 链接server
-
if (connect(connfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
-
printf("Connect error..\n");
-
exit(EXIT_FAILURE);
-
}
-
/*else
-
{
-
printf("Connet ok..\n");
-
} */
-
-
//!>
-
//!> send and recv
-
send_and_recv(connfd);
-
-
//!>
-
-
close(connfd);
-
printf("Exit\n");
-
-
return 0;
-
}
阅读(1378) | 评论(0) | 转发(0) |