#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <sys/epoll.h> /* epoll function */
#include <fcntl.h> /* nonblocking */
#include <sys/resource.h> /*setrlimit */
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define MAXEPOLLSIZE 10000
#define MAXLINE 10240
int handle(int connfd)
int setnonblocking(int sockfd)
{
if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
return -1
}
return 0
}
int main(int argc, char **argv)
{
int servPort = 6888
int listenq = 1024
int listenfd, connfd, kdpfd, nfds, n, nread, curfds,acceptCount = 0
struct sockaddr_in servaddr, cliaddr
socklen_t socklen = sizeof(struct sockaddr_in)
struct epoll_event ev
struct epoll_event events[MAXEPOLLSIZE]
struct rlimit rt
char buf[MAXLINE]
/* 设置每个进程允许打开的最大文件数 */
rt.rlim_max = rt.rlim_cur = MAXEPOLLSIZE
if (setrlimit(RLIMIT_NOFILE, &rt) == -1)
{
perror("setrlimit error")
return -1
}
bzero(&servaddr, sizeof(servaddr))
servaddr.sin_family = AF_INET
servaddr.sin_addr.s_addr = htonl(INADDR_ANY)
servaddr.sin_port = htons(servPort)
listenfd = socket(AF_INET, SOCK_STREAM, 0)
if (listenfd == -1) {
perror("can't create socket file")
return -1
}
int opt = 1
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))
if (setnonblocking(listenfd) < 0) {
perror("setnonblock error")
}
if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1)
{
perror("bind error")
return -1
}
if (listen(listenfd, listenq) == -1)
{
perror("listen error")
return -1
}
/* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */
kdpfd = epoll_create(MAXEPOLLSIZE)
ev.events = EPOLLIN | EPOLLET
ev.data.fd = listenfd
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev) < 0)
{
fprintf(stderr, "epoll set insertion error: fd=%d\n", listenfd)
return -1
}
curfds = 1
printf("epollserver startup,port %d, max connection is %d, backlog is %d\n", servPort, MAXEPOLLSIZE, listenq)
for () {
/* 等待有事件发生 */
nfds = epoll_wait(kdpfd, events, curfds, -1)
if (nfds == -1)
{
perror("epoll_wait")
continue
}
/* 处理所有事件 */
for (n = 0 n < nfds ++n)
{
if (events[n].data.fd == listenfd)
{
connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen)
if (connfd < 0)
{
perror("accept error")
continue
}
sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port)
printf("%d:%s", ++acceptCount, buf)
if (curfds >= MAXEPOLLSIZE) {
fprintf(stderr, "too many connection, more than %d\n", MAXEPOLLSIZE)
close(connfd)
continue
}
if (setnonblocking(connfd) < 0) {
perror("setnonblocking error")
}
ev.events = EPOLLIN | EPOLLET
ev.data.fd = connfd
if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev) < 0)
{
fprintf(stderr, "add socket '%d' to epoll failed: %s\n", connfd, strerror(errno))
return -1
}
curfds++
continue
}
// 处理客户端请求
if (handle(events[n].data.fd) < 0) {
epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev)
curfds--
}
}
}
close(listenfd)
return 0
}
int handle(int connfd) {
int nread
char buf[MAXLINE]
nread = read(connfd, buf, MAXLINE)//读取客户端socket流
if (nread == 0) {
printf("client close the connection\n")
close(connfd)
return -1
}
if (nread < 0) {
perror("read error")
close(connfd)
return -1
}
write(connfd, buf, nread)//响应客户端
return 0
}
epoll server端;
epoll client端
#include <unistd.h>#include <sys/types.h> /* basic system data types */
#include <sys/socket.h> /* basic socket definitions */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <netdb.h> /*gethostbyname function */
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define MAXLINE 1024
void handle(int connfd)
int main(int argc, char **argv)
{
char * servInetAddr = "127.0.0.1"
int servPort = 6888
char buf[MAXLINE]
int connfd
struct sockaddr_in servaddr
if (argc == 2) {
servInetAddr = argv[1]
}
if (argc == 3) {
servInetAddr = argv[1]
servPort = atoi(argv[2])
}
if (argc > 3) {
printf("usage: echoclient <IPaddress> <Port>\n")
return -1
}
connfd = socket(AF_INET, SOCK_STREAM, 0)
//bzero(&servaddr, sizeof(servaddr))
servaddr.sin_family = AF_INET
servaddr.sin_port = htons(servPort)
//inet_pton(AF_INET, servInetAddr, &servaddr.sin_addr)
servaddr.sin_addr.s_addr = inet_addr(servInetAddr)
bzero(&(servaddr.sin_zero), 0)
if (connect(connfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
perror("connect error")
return -1
}
printf("welcome to echoclient\n")
handle(connfd) /* do it all */
close(connfd)
printf("exit\n")
exit(0)
}
void handle(int sockfd)
{
char sendline[MAXLINE], recvline[MAXLINE]
int n
for () {
if (fgets(sendline, MAXLINE, stdin) == NULL)
{
break//read eof
}
n = write(sockfd, sendline, strlen(sendline))
n = read(sockfd, recvline, MAXLINE)
if (n == 0) {
printf("echoclient: server terminated prematurely\n")
break
}
write(STDOUT_FILENO, recvline, n)
}
}
其实大家如果对tcp/ip网络编程这一块不是很熟悉的话,还有一个好办法就是直接编写IO *** 作的程序,通过Xinetd来管理网络这一块,一样可以实现的,而且非常方便.这样就不需要别人帮你创建服务端了.
至于客户端,没有办法,如果可以的话,可以采用tcp工具替代,当然这些都是歪路子.
如果只是文件传输的话,就选用FTP原生的服务器吧,比自己折腾得稳定的多.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)