简单的,高性能,支持并发的Socket编程框架,容易使用,C语言实现。
tcp_server.h
---------------------------------
#ifndef TCP_SERVER_H
#define TCP_SERVER_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (ClientFunction)(int client);
void start_tcp_server_fork(int port, ClientFunction fp);
#ifdef __cplusplus
}
#endif
#endif
#include "tcp_server.h"
void sig_chld(int sig) {
pid_t pid;
int stat;
while ((pid = waitpid(-1, &stat, WNOHANG)) > 0)
printf("child %d termination\n", pid);
return;
}
void start_tcp_server_fork(int port, ClientFunction fp) {
printf("Start TCP Server at %d...\n", port);
int client_socket;
struct sockaddr_in sockaddr;
memset(&sockaddr, 0, sizeof (sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
sockaddr.sin_port = htons(port);
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
bind(listenfd, (struct sockaddr *) &sockaddr, sizeof (sockaddr));
listen(listenfd, 1024);
signal(SIGCHLD, sig_chld);
int child_pid;
while (1) {
struct sockaddr_in client_addr;
socklen_t slen = sizeof (client_addr);
client_socket = accept(listenfd, (struct sockaddr *) &client_addr, &slen);
printf("Client %s:%hu connected\n", inet_ntoa(client_addr.sin_addr), client_addr.sin_port);
if (client_socket < 0) {
printf("Accpet socket error: %s errno :%d\n", strerror(errno), errno);
continue;
}
child_pid = fork();
if (child_pid == 0) {
close(listenfd);
fp(client_socket);
close(client_socket);
exit(-6);
} else if (child_pid > 0)
close(client_socket);
}
close(listenfd);
}
主程序示例代码,demo.c
#include <stdio.h>
#include "tcp_server.h"
static ssize_t readch(int fd, char *ptr)
{
static int count = 0;
static char* read_ptr = 0;
static char read_buf[1024*4] = {0};
if (count <= 0)
{
again:
count = read(fd, read_buf, sizeof(read_buf));
if (-1 == count)
if (EINTR == errno)
goto again;
else
return -1;
else if (0 == count)
return 0;
read_ptr = read_buf;
}
count--;
*ptr = *read_ptr++;
return 1;
}
ssize_t readline(int fd, void *vptr, size_t maxlen)
{
ssize_t i = 0;
ssize_t ret = 0;
char ch = '\0';
char* ptr = NULL;
ptr = (char *)vptr;
for (i = 1; i < maxlen; ++i)
{
ret = readch(fd, &ch);
if (1 == ret)
{
*ptr++ = ch;
if ('\n' == ch)
break;
}
else if (0 == ret)
{
*ptr = 0;
return i-1;
}
else
return -1;
}
*ptr = 0;
return i;
}
void callback(int client)
{
char buf[4096];
write(client, "hello world\n", 12);
while (1) {
int len = readline(client, buf, sizeof(buf));
if (len<0) return;
write(client, "Server read: ", 13);
write(client, buf, len);
}
}
int main(int argc, char**argv) {
int i;
start_tcp_server_fork(8888, callback);
return 0;
}