server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <pthread.h>
#include <sys/ioctl.h>
#define true 1
#define false 0
#define MAX_EVENT_NUMBER 1024
#define BUFFER_SIZE 16
typedef struct recv_cmd {
int fd;
char buf[BUFFER_SIZE];
int len;
} recv_cmd_t;
int setnonblocking(int fd)
{
int old_option = fcntl(fd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
fcntl(fd, F_SETFL, new_option);
return old_option;
}
void addfd(int epollfd, int fd, int enable_et)
{
int ret = 0;
struct epoll_event event;
recv_cmd_t *cmd = (recv_cmd_t*)malloc(sizeof(recv_cmd_t));
if (cmd == NULL)
{
printf("add fd malloc cmd error!\n");
return;
}
memset(cmd, 0x00, sizeof(recv_cmd_t));
cmd->fd = fd;
cmd->len = 0;
event.data.ptr = cmd;
printf("add fd cmd:%p\n", cmd);
event.events = EPOLLIN;
if(enable_et){
event.events |= EPOLLET;
}
ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event );
if (ret != 0)
{
perror("epoll_ctl error");
return ;
}
setnonblocking(fd);
}
void do_event(struct epoll_event* events, int number, int epollfd, int listenfd)
{
int i=0;
int ret = 0;
struct in_addr addr1, addr2;
char buf_src[64] = {0};
char buf_dst[64] = {0};
for(i =0; i<number; i++){
recv_cmd_t *cmd = (recv_cmd_t *)events[i].data.ptr;
int sockfd = cmd->fd;
if(sockfd == listenfd) {
struct sockaddr_in client_address;
socklen_t client_addrlength = sizeof(client_address);
int connfd = accept(listenfd, (struct sockaddr* )&client_address, &client_addrlength);
if (connfd < 0)
{
perror("accept error");
return;
}
addfd(epollfd, connfd, true);/*对connfd开启ET模式*/
printf("server fd %d adding client on fd %d\n", listenfd, connfd);
}else if(events[i].events & EPOLLIN) {
ret = read(sockfd, cmd->buf+cmd->len, BUFFER_SIZE - cmd->len);
if(ret <= 0) {
if(errno == EAGAIN || errno == EWOULDBLOCK){
continue;
}else{
//
}
ret = epoll_ctl(epollfd, EPOLL_CTL_DEL, sockfd, &events[i]);
printf("epoll_ctl_del ret = %d\n", ret);
close(cmd->fd);
free(cmd);
continue;
}
cmd->len += ret;
if (cmd->len < 12) {
printf("recv fd=%d, len:%d too short!\n", events[i].data.fd, ret);
continue;
}
memcpy(&addr1, cmd->buf+4, 4); //复制IP地址
sprintf(buf_src, "%s", inet_ntoa(addr1));
memcpy(&addr2, cmd->buf+8, 4); //复制IP地址
sprintf(buf_dst, "%s", inet_ntoa(addr2));
printf("msg:%x,%x,%d,%s,%s \n", cmd->buf[0], cmd->buf[1], ntohs(*(unsigned short*)(cmd->buf+2)), buf_src, buf_dst);
buf_src[0] = 0x05;
buf_src[1] = 0x00;
ret = write(sockfd, buf_src, 2);
printf("serving write client on fd %d, %d\n", sockfd, ret);
}else{
printf("something else happen\n");
}
}
}
int main()
{
int ret = 0;
int opt = 1;
struct sockaddr_in address;
bzero(&address, sizeof(address));
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd < 0)
{
perror("socket error");
return -1;
}
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt));
address.sin_family = AF_INET;
address.sin_addr.s_addr = htonl(INADDR_ANY);
address.sin_port = htons(8888);
ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
if (ret != 0)
{
perror("bind error");
return -1;
}
ret = listen(listenfd, 5);
if (ret != 0)
{
perror("listen error");
return -1;
}
struct epoll_event *events;
events = (struct epoll_event *)malloc(MAX_EVENT_NUMBER * sizeof(struct epoll_event));
memset(events, 0x00, sizeof(events));
int epollfd = epoll_create(5);
assert(epollfd != -1);
addfd(epollfd, listenfd, true);/*对connfd开启ET模式*/
while(1){
int ret = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
if(ret<0){
printf("epoll wait failure\n");
break;
}
do_event(events, ret, epollfd, listenfd);
}
close(listenfd);
return 0;
}
client.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
int main()
{
int client_sockfd;
int len;
struct sockaddr_in address;//服务器端网络地址结构体
int result;
unsigned char buf[128] = {0};
client_sockfd = socket(AF_INET, SOCK_STREAM, 0);//建立客户端socket
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr("127.0.0.1");
address.sin_port = htons(8888);
len = sizeof(address);
result = connect(client_sockfd, (struct sockaddr *)&address, len);
if(result == -1)
{
perror("oops: client2");
exit(1);
}
printf("client_sockfd = %d\n", client_sockfd);
buf[0] = 0x05;
buf[1] = 0x09;
int appaddr = inet_addr("192.168.9.112");
int appaddr1 = inet_addr("192.168.9.113");
unsigned short appport = htons(8080);
memcpy(buf + 2, &appport, sizeof(appport));
write(client_sockfd, buf, 4);
sleep(1);
memcpy(buf, &appaddr, sizeof(appaddr));
memcpy(buf + 4, &appaddr1, sizeof(appaddr1));
write(client_sockfd, buf, 8);
printf("first client write over!\n");
result = read(client_sockfd, buf, sizeof(buf));
printf("from server len:%d %x,%x \n",result, buf[0], buf[1]);
close(client_sockfd);
return 0;