您的位置:首页 > 理论基础 > 计算机网络

通过TCP协议实现多个client端可以并发连接到server,client可获得server指定目录下的文件列表。

2016-07-20 23:38 525 查看
快被if语句坑死了,找错一定要注意判断错误时候的if语句,搞错了真难找原因

服务端代码如下:

/*
============================================================================
Name : qqepoll.c
Author :
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/epoll.h>
#include <dirent.h>

#define BUFSIZE 262144

void getdir(const char *dirname, char *buf)
{
DIR *dp;
struct dirent *dirp;
dp = opendir(dirname);
if (dp == NULL)
{
printf("error is %s\n", strerror(errno));
strcpy(buf, strerror(errno));
return;
}
char tmp[200];

while ((dirp = readdir(dp)) != NULL)
{
memset(tmp, 0, sizeof(tmp));
sprintf(tmp, "%s\n", dirp->d_name);
strcat(buf, tmp);
}
closedir(dp);
return;
}

int socket_recv(int st)
{
char buf[1024];
memset(buf, 0, sizeof(buf));
char *sendbuf = malloc(BUFSIZE);
memset(sendbuf, 0, BUFSIZE);
ssize_t rc = recv(st, buf, sizeof(buf), 0);

if (rc <= 0)
{
printf("recv is failed %s\n", strerror(errno));
}
else
{
printf("recv is %s\n", buf);
getdir(buf, sendbuf);
printf("send is %s\n", sendbuf);
send(st, sendbuf, strlen(sendbuf), 0);
}
free(sendbuf);
return rc;
}

void setnonblocking(int st)
{
int opts = fcntl(st, F_GETFL);
if (opts < 0)
{
printf("fcntl is failed %s\n", strerror(errno));
return;
}
opts = opts | O_NONBLOCK;
if (fcntl(st, F_SETFL, opts))
{
printf("fcntl is failed %s\n", strerror(errno));
}
}

int socket_create(int port)
{
int st = socket(AF_INET, SOCK_STREAM, 0);
int on = 1;
if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
{
printf("setsockopt is failed %s\n", strerror(errno));
return 0;
}
struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(st, (struct sockaddr *) &addr, sizeof(addr)) == -1)
{
printf("bind is failed %s\n", strerror(errno));
return 0;
}
if (listen(st, 300) == -1)
{
printf("listen is failed %s\n", strerror(errno));
return 0;
}
return st;
}

int socket_accept(int listen_st)
{
struct sockaddr_in client_addr;
socklen_t len = sizeof(client_addr);
memset(&client_addr, 0, sizeof(client_addr));
int client_st = accept(listen_st, (struct sockaddr*) &client_addr, &len);
if (client_st < 0)
{
printf("accept is failed %s\n", strerror(errno));
} else
{
printf("accept by %s\n", inet_ntoa(client_addr.sin_addr));
}
return client_st;
}

void run(int port)
{
int listen_st = socket_create(port);
setnonblocking(listen_st);
struct epoll_event ev, events[200];

int epfd = epoll_create(200);

ev.data.fd = listen_st;
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
epoll_ctl(epfd, EPOLL_CTL_ADD, listen_st, &ev);

int st = 0;
while (1)
{
int nfds = epoll_wait(epfd, events, 200, -1);
if (nfds == -1)
{
printf("epoll_wait is failed %s\n", strerror(errno));
break;
}

int i = 0;
for (; i < nfds; i++)
{
if (events[i].data.fd < 0)
continue;
if (events[i].data.fd == listen_st)
{
st = socket_accept(listen_st);
if (st >= 0)
{
setnonblocking(st);
ev.data.fd = st;
ev.events = EPOLLIN | EPOLLERR | EPOLLHUP;
epoll_ctl(epfd, EPOLL_CTL_ADD, st, &ev);
continue;
}
}
if (events[i].events & EPOLLIN)
{
st = events[i].data.fd;
if (socket_recv(st) <= 0)
{
close(st);
events[i].data.fd = -1;
}
}
if (events[i].events & EPOLLERR)
{
st = events[i].data.fd;
close(st);
events[i].data.fd = -1;
}
if (events[i].events & EPOLLHUP)
{
st = events[i].data.fd;
close(st);
events[i].data.fd = -1;
}
}
}
close(epfd);
}

int main(int arg, char *args[])
{
if (arg < 2)
{
return 0;
}
int iport = atoi(args[1]);
if (iport == 0)
{
printf("port %d is invalid\n", iport);
return 0;
}

run(iport);
return 0;
}



客户端代码如下:
/*
* client.c
*
* Created on: 2016年7月20日
* Author: Administrator
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>

#define BUFSIZE 262144

int socket_connect(const char *hostname, int port)
{
int client_st = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(hostname);

if (connect(client_st, (struct sockaddr *)&addr, sizeof(addr)) == -1)
{
printf("connect is failed %s\n", strerror(errno));
return 0;
}
return client_st;
}

int socket_send(int st, const char *s)
{
int rc = send(st, s, strlen(s), 0);
if (rc <= 0)
{
printf("send failed, %s\n", strerror(errno));
return rc;
}

char *buf = malloc(BUFSIZE);
memset(buf, 0, BUFSIZE);
rc = recv(st, buf, BUFSIZE, 0);
if (rc <= 0)
{
printf("recv failedxin, %s\n", strerror(errno));
}
else
{
printf("%s\n", buf);
}
free(buf);
return rc;
}

int main(int arg, char *args[])
{
if (arg < 3)
{
return 0;
}
int iport = atoi(args[2]);
if (iport == 0)
{
printf("port %d is invalid\n", iport);
return 0;
}
int st = socket_connect(args[1], iport);
if (st == 0)
{
return 0;
}
char buf[200];
while (1)
{
memset(buf, 0, sizeof(buf));
read(STDIN_FILENO, buf, sizeof(buf)); // 从键盘读取用户输入

if (strncmp(buf, "exit", 4) == 0)
break;

buf[strlen(buf) - 1] = 0;
if (strlen(buf) == 0)
continue;
if (socket_send(st, buf) <= 0)
break;
}
close(st);

return 0;
}


makefile文件

.SUFFIXES:.c .o

CC=gcc
SRCS1=qqepoll.c
SRCS2=client.c

OBJS1=$(SRCS1:.c=.o)
OBJS2=$(SRCS2:.c=.o)
EXEC1=epoll
EXEC2=client

start: $(OBJS1) $(OBJS2)
$(CC) -o $(EXEC1) $(OBJS1)
$(CC) -o $(EXEC2) $(OBJS2)
@echo '----------------ok------------'

.c.o:
$(CC) -o $@ -c $<

clean:
rm -f $(OBJS)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: