1、通过TCP协议实现多个client端可以并发连接到server,client可获得server指定目录下的文件列表。
/*
* client.c
*
* Created on: 2016年11月3日
* Author: Administrator
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 10240
int socket_connect(const char*hostname, int port)
{
int client_st = socket(AF_INET, SOCK_STREAM, 0);
if (client_st == -1)
{
printf("socket failed %s\n", strerror(errno));
return -1;
}
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 failed %s\n", strerror(errno));
return -1;
} else
{
printf("connect to %s:%d\n", hostname, port);
return client_st;
}
}
int socket_send_dir(int client_st, const char *dir)
{
int rc = send(client_st, dir, strlen(dir), 0);
if (rc <= 0)
{
printf("send failed %s\n", strerror(errno));
return rc;
}
char *buf = malloc(BUFSIZE);
memset(buf, 0, BUFSIZE);
rc = recv(client_st, buf, BUFSIZE, 0);
if (rc <= 0)
{
printf("recv failed %s\n", strerror(errno));
return rc;
}else
{
printf("%s\n", buf);//如果接收到来自server端的数据,将数据打印到屏幕
}
free(buf);
return rc;
}
int main(int arg, char*args[])
{
if (arg < 3)
{
printf("usage:client hostname port\n");
return 0;
}
int iport = atoi(args[2]);
if (iport == 0)
{
printf("port %d is invaild\n", iport);
return 0;
}
int client_st = socket_connect(args[1], iport);
if (client_st == -1)
{
printf("socket_connect failed\n");
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_dir(client_st, buf) <= 0)
break;
}
close(client_st);
return EXIT_SUCCESS;
}
/*
============================================================================
Name : CS-opendir.c
Author : Allen
Version :
Copyright : Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 10240
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 failed %s\n", strerror(errno));
return 0;
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if ((bind(st, (struct sockaddr*) &server_addr, sizeof(server_addr))) == -1)
{
printf("bind failed %s\n", strerror(errno));
return -1;
}
if ((listen(st, 20)) == -1)
{
printf("listen failed %s\n", strerror(errno));
return -1;
}
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 == -1)
{
printf("accpet failed %s\n", strerror(errno));
return -1;
} else
{
printf("accept by %s\n", inet_ntoa(client_addr.sin_addr));
}
return client_st;
}
void getdir(const char*dirname, char*buf)
{
DIR *dp;
dp = opendir(dirname);
if (dp == NULL)
{
printf("opendir failed %s\n", strerror(errno));
return;
}
struct dirent *dirp;
char tmp[200];
while ((dirp = readdir(dp)) != NULL)
{
memset(tmp, 0, sizeof(tmp));
sprintf(tmp, "%s ", dirp->d_name);
strcat(buf, tmp);
}
closedir(dp);
return;
}
int socket_recv(int client_st)
{
char recvbuf[200];
memset(recvbuf, 0, sizeof(recvbuf));
char *sendbuf = malloc(BUFSIZE);
memset(sendbuf, 0, BUFSIZE);
int rc = recv(client_st, recvbuf, sizeof(recvbuf), 0);
printf("收到客户端的消息是:%s\n", recvbuf);
if (rc <= 0)
{
printf("recv failed %s\n", strerror(errno));
} else
{
getdir(recvbuf, sendbuf);
rc = send(client_st, sendbuf, strlen(sendbuf), 0);
if (rc <= 0)
{
printf("send failed %s\n", strerror(errno));
}
}
free(sendbuf);
//close(client_st);
return rc;
}
int setnonblocking(int st) //将socket设置为非阻塞
{
int opts = fcntl(st, F_GETFL);
if (opts < 0)
{
printf("fcntl failed %s\n", strerror(errno));
return 0;
}
opts = opts | O_NONBLOCK;
if (fcntl(st, F_SETFL, opts) < 0)
{
printf("fcntl failed %s\n", strerror(errno));
return 0;
}
return 1;
}
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;
while (1)
{
int nfds = epoll_wait(epfd, events, 200, -1);
if (nfds == -1)
{
printf("epoll_wait 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) //如果没有参数,main函数退出
{
printf("usage:server port\n");
return EXIT_SUCCESS;
}
int iport = atoi(args[1]); //将第一个参数转化为端口号
if (iport == 0)
{
printf("port %d is invalid\n", iport);
return EXIT_SUCCESS;
}
run(iport);
return EXIT_SUCCESS;
}
.SUFFIXES: .c .o
CC=gcc
SRCS1=server.c
SRCS2=client.c
OBJS1=$(SRCS1:.c=.o)
OBJS2=$(SRCS2:.c=.o)
EXEC1=server
EXEC2=client
all: $(OBJS1) $(OBJS2)
$(CC) -o $(EXEC1) $(OBJS1)
$(CC) -o $(EXEC2) $(OBJS2)
@echo '-------------ok--------------'
.c.o:
$(CC) -Wall -g -o $@ -c $<
clean:
rm -f $(OBJS1) $(OBJS2)
rm -f core*
今天没时间为代码注释啦,改天补齐.