linux下的http服务器

1.以下是我上一篇文字《linux下的http服务器代码》整理出来修改本地编译通过的代码:

代码来源:本次转帖来源:http://www.cnblogs.com/xiaouisme/archive/2012/05/26/2519314.html

/* code c, change the DEFAULTIP to your localhost IP*/

#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <signal.h>
#include <getopt.h>

#define DEFAULTIP "10.2.3.51"
#define DEFAULTPORT "80"
#define DEFAULTBACK "10"
#define DEFAULTDIR "/home/temp/http_server"
#define DEFAULTLOG "/home/temp/http_server/das-server.log"

void prterrmsg(char *msg);
#define prterrmsg(msg)        { perror(msg); abort(); }
void wrterrmsg(char *msg);
#define wrterrmsg(msg)        { fputs(msg, logfp); fputs(strerror(errno), logfp);fflush(logfp); abort(); }

void prtinfomsg(char *msg);
#define prtinfomsg(msg)        { fputs(msg, stdout);  }
void wrtinfomsg(char *msg);
#define wrtinfomsg(msg)        {  fputs(msg, logfp); fflush(logfp);}

#define MAXBUF        1024

char buffer[MAXBUF + 1];
char *host = 0;
char *port = 0;
char *back = 0;
char *dirroot = 0;
char *logdir = 0;
unsigned char daemon_y_n = 0;
FILE *logfp;

#define MAXPATH        150

/*----------------------------------------
*--- dir_up - 查找dirpath所指目录的上一级目录
*----------------------------------------
*/
char *dir_up(char *dirpath)
{
	static char Path[MAXPATH];
	int len;

	strcpy(Path, dirpath);
	len = strlen(Path);
	if (len > 1 && Path[len - 1] == '/')
	{
		len--;
	}
	while (Path[len - 1] != '/' && len > 1)
	{
		len--;
	}
	Path[len] = 0;
	return Path;
}

/*------------------------------------------------------
*--- AllocateMemory - 分配空间并把d所指的内容复制
*------------------------------------------------------
*/
void AllocateMemory(char **s, int l, char *d)
{
	*s = malloc(l + 1);
	bzero(*s, l + 1);
	memcpy(*s, d, l);
}

/************关于本文档********************************************
*filename: das-server.c
*purpose: 这是在Linux下用C语言写的目录访问服务器,支持目录浏览和文件下载

*********************************************************************/
/*------------------------------------------------------
*--- GiveResponse - 把Path所指的内容发送到client_sock去
*-------------------如果Path是一个目录,则列出目录内容
*-------------------如果Path是一个文件,则下载文件
*------------------------------------------------------
*/
void GiveResponse(FILE * client_sock, char *Path)
{
	struct dirent *dirent;
	struct stat info;
	char Filename[MAXPATH];
	DIR *dir;
	int fd, len, ret;
	char *p, *realPath, *realFilename, *nport;

	/* 获得实际工作目录或文件 */
	len = strlen(dirroot) + strlen(Path) + 1;
	realPath = malloc(len + 1);
	bzero(realPath, len + 1);
	sprintf(realPath, "%s/%s", dirroot, Path);

	/* 获得实际工作端口 */
	len = strlen(port) + 1;
	nport = malloc(len + 1);
	bzero(nport, len + 1);
	sprintf(nport, ":%s", port);

	/* 获得实际工作目录或文件的信息以判断是文件还是目录 */
	if (stat(realPath, &info))
	{
		fprintf(client_sock,
		     "HTTP/1.1 200 OK\r\nServer:SONG\r\nConnection: close\r\nContent-Type:text/html; charset=UTF-8\r\n\r\n<html><head><title>%d - %s</title></head>"
		     "<body><font size=+4>Linux directory access server</font><br><hr width=\"100%%\"><br><center>"
		     "<table border cols=3 width=\"100%%\">", errno,
		     strerror(errno));
		fprintf(client_sock,
		     "</table><font color=\"CC0000\" size=+2>Please contact the administrator consulting why appear as follows error message:\n%s %s</font></body></html>",
		     Path, strerror(errno));
		goto out;
	}
	/* 处理浏览文件请求,即下载文件 */
	if (S_ISREG(info.st_mode))
	{
		fd = open(realPath, O_RDONLY);
		len = lseek(fd, 0, SEEK_END);
		p = (char *) malloc(len + 1);
		bzero(p, len + 1);
		lseek(fd, 0, SEEK_SET);
		ret = read(fd, p, len);
		close(fd);
		fprintf(client_sock,
		     "HTTP/1.1 200 OK\r\nServer:SONG\r\nConnection: keep-alive\r\nContent-type: application/*\r\nContent-Length:%d\r\n\r\n",
		     len);
		fwrite(p, len, 1, client_sock);
		free(p);
	}
	else if (S_ISDIR(info.st_mode))
	{
		/* 处理浏览目录请求 */
		dir = opendir(realPath);
		fprintf(client_sock,
		     "HTTP/1.1 200 OK\r\nServer:SONG\r\nConnection: close\r\nContent-Type:text/html; charset=UTF-8\r\n\r\n<html><head><title>%s</title></head>"
		     "<body><font size=+4>Linux directory access server</font><br><hr width=\"100%%\"><br><center>"
		     "<table border cols=3 width=\"100%%\">", Path);
		fprintf(client_sock,
		     "<caption><font size=+3>dir %s</font></caption>\n",
		     Path);
		fprintf(client_sock,
		     "<tr><td>name</td><td>大小</td><td>change time</td></tr>\n");
		if (dir == 0)
		{
			fprintf(client_sock,
			     "</table><font color=\"CC0000\" size=+2>%s</font></body></html>",
			     strerror(errno));
			return;
	 	}
		/* 读取目录里的所有内容 */
		while ((dirent = readdir(dir)) != 0)
		{
			if (strcmp(Path, "/") == 0)
			{
				sprintf(Filename, "/%s", dirent->d_name);
			}
			else
			{
				sprintf(Filename, "%s/%s", Path, dirent->d_name);
			}
			fprintf(client_sock, "<tr>");
			len = strlen(dirroot) + strlen(Filename) + 1;
			realFilename = malloc(len + 1);
			bzero(realFilename, len + 1);
			sprintf(realFilename, "%s/%s", dirroot, Filename);
			if (stat(realFilename, &info) == 0)
			{
				if (strcmp(dirent->d_name, "..") == 0)
				{
					fprintf(client_sock,
					     "<td><a href=\"http://%s%s%s\">(parent)</a></td>",
					     host, atoi(port) == 80 ? "" : nport,
					     dir_up(Path));
				}
				else
				{
					fprintf(client_sock,
					     "<td><a href=\"http://%s%s%s\">%s</a></td>",
					     host, atoi(port) == 80 ? "" : nport, Filename,
					     dirent->d_name);
				}
				if (S_ISDIR(info.st_mode))
				{
					fprintf(client_sock, "<td>dir</td>");
				}
				else if (S_ISREG(info.st_mode))
				{
					fprintf(client_sock, "<td>%d</td>", info.st_size);
				}
				else if (S_ISLNK(info.st_mode))
				{
					fprintf(client_sock, "<td>interlinkage</td>");
				}
				else if (S_ISCHR(info.st_mode))
				{
					fprintf(client_sock, "<td>char device</td>");
				}
				else if (S_ISBLK(info.st_mode))
				{
					fprintf(client_sock, "<td>chunk device</td>");
				}
				else if (S_ISFIFO(info.st_mode))
				{
					fprintf(client_sock, "<td>FIFO</td>");
				}
				else if (S_ISSOCK(info.st_mode))
				{
					fprintf(client_sock, "<td>Socket</td>");
				}
				else
				{
					fprintf(client_sock, "<td>(unknow)</td>");
					fprintf(client_sock, "<td>%s</td>", ctime(&info.st_ctime));
				}
			}
			fprintf(client_sock, "</tr>\n");
			free(realFilename);
		}
		fprintf(client_sock, "</table></center></body></html>");
	}
	else
	{
		/* 既非常规文件又非目录,禁止访问 */
		fprintf(client_sock,
		    "HTTP/1.1 200 OK\r\nServer:SONG\r\nConnection: close\r\nContent-Type:text/html; charset=UTF-8\r\n<html><head><title>permission denied</title></head>"
		    "<body><font size=+4>Linux directory access server</font><br><hr width=\"100%%\"><br><center>"
		     "<table border cols=3 width=\"100%%\">");
		fprintf(client_sock,
		     "</table><font color=\"CC0000\" size=+2>You visit resources '%s' be under an embargo,Please contact the administrator to solve!</font></body></html& gt;",
		     Path);
	}
out:
	free(realPath);
	free(nport);
}

/*------------------------------------------------------
*--- getoption - 分析取出程序的参数
*------------------------------------------------------
*/
void getoption(int argc, char **argv)
{
	int c, len;
	char *p = 0;

	opterr = 0;
	while (1)
	{
		int option_index = 0;
		static struct option long_options[] =
		{
			{"host", 1, 0, 0},
			{"port", 1, 0, 0},
			{"back", 1, 0, 0},
			{"dir", 1, 0, 0},
			{"log", 1, 0, 0},
			{"daemon", 0, 0, 0},
			{0, 0, 0, 0}
		};

		/* 本程序支持如一些参数:
		* --host IP地址 或者 -H IP地址
		* --port 端口 或者 -P 端口
		* --back 监听数量 或者 -B 监听数量
		* --dir 网站根目录 或者 -D 网站根目录
		* --log 日志存放路径 或者 -L 日志存放路径
		* --daemon 使程序进入后台运行模式
		*/
		c = getopt_long(argc, argv, "H:P:B:D:L", long_options, &option_index);
		if (c == -1 || c == '?')
		{
			break;
		}

		if(optarg)
		{
			len = strlen(optarg);
		}
		else
		{
			len = 0;
		}

		if ((!c && !(strcasecmp(long_options[option_index].name, "host"))) || c == 'H')
		{
			p = host = malloc(len + 1);
		}
		else if ((!c &&	!(strcasecmp(long_options[option_index].name, "port")))	|| c == 'P')
		{
			p = port = malloc(len + 1);
		}
		else if ((!c &&	!(strcasecmp(long_options[option_index].name, "back")))	|| c == 'B')
		{
			p = back = malloc(len + 1);
		}
		else if ((!c && !(strcasecmp(long_options[option_index].name, "dir"))) || c == 'D')
		{
			p = dirroot = malloc(len + 1);
		}
		else if ((!c && !(strcasecmp(long_options[option_index].name, "log"))) || c == 'L')
		{
			p = logdir = malloc(len + 1);
		}
		else if ((!c &&	!(strcasecmp(long_options[option_index].name, "daemon"))))
		{
			daemon_y_n = 1;
			continue;
		}
		else
		{
			break;
		}
		bzero(p, len + 1);
		memcpy(p, optarg, len);
	}
}

int main(int argc, char **argv)
{
	struct sockaddr_in addr;
	struct sockaddr_in my_addr;
	my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	int sock_fd, addrlen;

	/* 获得程序工作的参数,如 IP 、端口、监听数、网页根目录、目录存放位置等 */
	getoption(argc, argv);

	if (!host)
	{
		addrlen = strlen(DEFAULTIP);
		AllocateMemory(&host, addrlen, DEFAULTIP);
	}
	if (!port)
	{
		addrlen = strlen(DEFAULTPORT);
		AllocateMemory(&port, addrlen, DEFAULTPORT);
	}
	if (!back)
	{
		addrlen = strlen(DEFAULTBACK);
		AllocateMemory(&back, addrlen, DEFAULTBACK);
	}
	if (!dirroot)
	{
		addrlen = strlen(DEFAULTDIR);
		AllocateMemory(&dirroot, addrlen, DEFAULTDIR);
	}
	if (!logdir)
	{
		addrlen = strlen(DEFAULTLOG);
		AllocateMemory(&logdir, addrlen, DEFAULTLOG);
	}

	printf("host=%s port=%s back=%s dirroot=%s logdir=%s %s work mode is background(progress ID:%d)\n", host, port, back, dirroot, logdir, daemon_y_n?"":"no", getpid());

	/* fork() 两次处于后台工作模式下 */
	if (daemon_y_n)
	{
		if (fork())
		{
			exit(0);
		}
		if (fork())
		{
			exit(0);
		}
		close(0), close(1), close(2);
		logfp = fopen(logdir, "a+");
		if (!logfp)
		{
			exit(0);
		}
	}

	/* 处理子进程退出以免产生僵尸进程 */
	signal(SIGCHLD, SIG_IGN);

	/* 创建 socket */
	if ((sock_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
	{
		if (!daemon_y_n)
		{
			prterrmsg("socket()");
		}
		else
		{
			wrterrmsg("socket()");
		}
	}

	/* 设置端口快速重用 */
	addrlen = 1;
	setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen,	sizeof(addrlen));

	addr.sin_family = AF_INET;
	addr.sin_port = htons(atoi(port));
	addr.sin_addr.s_addr = inet_addr(host);//htonl(INADDR_ANY);
	addrlen = sizeof(struct sockaddr_in);
	/* 绑定地址、端口等信息 */
	if (bind(sock_fd, (struct sockaddr *) &addr, addrlen) < 0)
	{
		if (!daemon_y_n)
		{
			prterrmsg("bind()");
		}
		else
		{
			wrterrmsg("bind()");
		}
	}

	/* 开启临听 */
	if (listen(sock_fd, atoi(back)) < 0)
	{
		if (!daemon_y_n)
		{
			prterrmsg("listen()");
		}
		else
		{
			wrterrmsg("listen()");
		}
	}
	while (1)
	{
		int len;
		int new_fd;
		addrlen = sizeof(struct sockaddr_in);
		/* 接受新连接请求 */
		new_fd = accept(sock_fd, (struct sockaddr *) &addr, &addrlen);
		if (new_fd < 0)
		{
			if (!daemon_y_n)
			{
				prterrmsg("accept()");
	        }
			else
			{
				wrterrmsg("accept()");
			}
			break;
		}
		bzero(buffer, MAXBUF + 1);
		sprintf(buffer, "connect from: %s:%d\n",inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
		if (!daemon_y_n)
		{
			prtinfomsg(buffer);
		}
		else
		{
			wrtinfomsg(buffer);
		}

		/* 产生一个子进程去处理请求,当前进程继续等待新的连接到来 */
		//if (!fork())			// 改为只有第一次连上能发送数据
		{
			bzero(buffer, MAXBUF + 1);
			if ((len = recv(new_fd, buffer, MAXBUF, 0)) > 0)
			{
				FILE *ClientFP = fdopen(new_fd, "w");
				if (ClientFP == NULL)
				{
					if (!daemon_y_n)
					{
						prterrmsg("fdopen()");
					}
					else
					{
						prterrmsg("fdopen()");
					}
				}
				else
				{
					char Req[MAXPATH + 1] = "";
					sscanf(buffer, "GET %s HTTP", Req);
					bzero(buffer, MAXBUF + 1);
					sprintf(buffer, "read file: \"%s\"\n", Req);
					if (!daemon_y_n)
					{
						prtinfomsg(buffer);
					}
					else
					{
						wrtinfomsg(buffer);
					}
					/* 处理用户请求 */
					GiveResponse(ClientFP, Req);
					fclose(ClientFP);
				}
			}
			exit(0);
		}
		close(new_fd);
	}
	close(sock_fd);
	return 0;
}


2.下面是另外一个,这个服务器连接上之后会将所有的数据发送的,本地编译运行通过的:

源代码出处忘记记录了。。。

/**************filename: Server.cpp****************
 该程序通过标准socket实现简单Http服务器
 运行该服务器可以通过浏览器访问服务器目录下的
 Html文件和jpg图片 完成初步的Http服务器功能
***************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <netinet/in.h>

#define SERVER_PORT 8089		// 自定义的服务端口
#define HOSTLEN 256				// 主机名长度
#define BACKLOG 10				// 同时等待的连接个数

/**************************************
 该方法包装了send()
 通过该方法发送数据 能够全部发出
 没有遗漏
**************************************/
int sendall(int s, char *buf, int *len)
{
	int total = 0;				// 已经发送字节数
	int bytesleft = *len;		// 还剩余多少字节
	int n;
	while(total < *len)
	{
		n = send(s, buf + total, bytesleft, 0);
		if (n == -1)
		{
			break;
		}
		total += n;
		bytesleft -= n;
	}
	*len = total;				// 返回实际发送出去的字节数
	return n==-1 ? -1 : 0;		// 成功发送返回0 失败-1
}

/**************************************
 该方法处理错误请求
 并向客户端发送错误信息
**************************************/
void wrong_req(int sock) {
	char* error_head = "HTTP/1.0 501 Not Implemented\r\n"; // 输出501错误
	int len = strlen(error_head);
	if (sendall(sock, error_head, &len) == -1)		// 向客户发送
	{
		printf("Sending failed!");
		return;
	}

	char* error_type = "Content-type: text/plain\r\n";
	len = strlen(error_type);
	if (sendall(sock, error_type, &len) == -1)
	{
		printf("Sending failed!");
		return;
	}

	char* error_end = "\r\n";
	len = strlen(error_end);
	if (sendall(sock, error_end, &len) == -1)
	{
		printf("Sending failed!");
		return;
	}

	char* prompt_info = "The command is not yet completed\r\n";
	len = strlen(prompt_info);
	if (sendall(sock, prompt_info, &len) == -1)
	{
		printf("Sending failed!");
		return;
	}
}

/**********************************
 该方法判断用户请求的文件是否存在
 不存在返回非0 存在返回0
***********************************/
int not_exit(char* arguments)
{
	struct stat dir_info;
	//return (stat(arguments, &dir_info) == -1);
	return access(arguments, 0);
}

/*************************************
 所请求的文件不存在
*************************************/
void file_not_found(char* arguments, int sock)
{
	char* error_head = "HTTP/1.0 404 Not Found\r\n";	// 构造404错误head
	int len = strlen(error_head);
	if (sendall(sock, error_head, &len) == -1)			// 向客户端发送
	{
		printf("Sending error!");
		return;
	}

	char* error_type = "Content-type: text/plain\r\n";
	len = strlen(error_type);
	if (sendall(sock, error_type, &len) == -1)
	{
		printf("Sending error!");
		return;
	}

	char* error_end = "\r\n";
	len = strlen(error_end);
	if (sendall(sock, error_end, &len) == -1)
	{
		printf("Sending error!");
		return;
	}

	char prompt_info[50] = "Not found:  ";
	strcat(prompt_info, arguments);
	len = strlen(prompt_info);
	if (sendall(sock, prompt_info, &len) == -1)			// 输出未找到的文件
	{
		printf("Sending error!");
		return;
	}
}

/*************************************
 发送Http协议头部信息
 其中包括响应类型和Content Type
*************************************/
void send_header(int send_to, char* content_type)
{
	char* head = "HTTP/1.0 200 OK\r\n";     // 正确的头部信息
	int len = strlen(head);
	if (sendall(send_to, head, &len) == -1)	// 向连接的客户端发送数据
	{
		printf("Sending error");
		return;
	}

	if (content_type)						// content_type不为空
	{
		char temp_1[125] = "Content-Disposition: attachment\r\nContent-type: ";	// 准备好要连接的字串
		//char temp_1[125] = "Content-type: ";	// 准备好要连接的字串
		strcat(temp_1, content_type);		// 构造content_type
		strcat(temp_1, "\r\n");
		len = strlen(temp_1);
		if (sendall(send_to, temp_1, &len) == -1)
		{
			printf("Sending error!");
			return;
		}
	}
}

/***********************************
 取得用户所请求的文件类型
 即文件后缀 (.html .jpg .gif)
************************************/
char* file_type(char* arg)
{
	char * temp;          					// 临时字符串指针
	if ((temp = strrchr(arg, '.')) != NULL)	// 取得后缀
	{
		return temp + 1;
	}
	return "";           					// 如果请求的文件名中没有. 则返回空串
}

/*************************************
 该方法为程序核心
 负责真正发送文件 如*.html *.jpg等
*************************************/
void send_file(char* arguments, int sock)
{
	char* extension = file_type(arguments);	// 获得文件后缀名
	//char* content_type = "text/plain";		// 初始化type='text/plain'
	char* content_type = "application/octet-stream";
	FILE* read_from;						// 本地文件指针从该文件中读取.html .jpg等
	int readed = -1, file_len = 0;			// 每次读得的字节数、文件总长度
	char read_buf[256] = {0};				// 读文件时的字节缓存数组
	char *file_buf = NULL;					// 文件内容
	char *szTmp = NULL;
	int tmp_len = 0;
	static char num = 0;

	printf("send_file\n");
	if (strcmp(extension, "html") == 0)		// 发送内容为html
	{
		content_type = "text/html";
	}

	if (strcmp(extension, "gif") == 0)		// 发送内容为gif
	{
		content_type = "image/gif";
	}

	if (strcmp(extension, "jpg") == 0)		// 发送内容为jpg
	{
		content_type = "image/jpg";
	}

	read_from = fopen(arguments, "rb");		// 打开用户指定的文件准备读取
	if (read_from != NULL)					// 指针不为空
	{
		fseek(read_from, 0, SEEK_SET);
		fseek(read_from, 0, SEEK_END);		
		file_len = ftell(read_from);
		file_buf = (char *)malloc(file_len + 1);
		if (file_buf == NULL)
		{
			printf("malloc error!");
		}
		memset(file_buf, 0, file_len + 1);
		
		szTmp = file_buf;
		fseek(read_from, 0, SEEK_SET);
		while (!feof(read_from))
		{
			memset(read_buf, 0, sizeof (read_buf));
			readed = fread(read_buf, 1, sizeof(read_buf), read_from);
			if (readed <= 0)
			{
				continue;
			}
			memcpy(szTmp, read_buf, readed);
			szTmp += readed;
			tmp_len += readed;
		}
		fclose(read_from);
		
		printf("file_len = %d, tmp_len = %d\n", file_len, tmp_len);
		
		send_header(sock, content_type);    // 发送协议头
		memset(read_buf, 0, sizeof (read_buf));
		sprintf(read_buf, "Content-Length: %d\r\n", file_len);
		tmp_len = strlen(read_buf);
		if (sendall(sock, read_buf, &tmp_len) == -1)
		{
			printf("Sending error!");
			return;
		}
		send(sock, "\r\n", 2, 0);			// 再加一个"\r\n" 不能缺少 格式要求
		
		if (num != 0)
		{
			printf("no send because num = %d\n", num);
			return;
		}
		
		if (sendall(sock, file_buf, &file_len) == -1)// 发送数据
		{
			printf("Sending file_buf error!\n");   // 出现发送错误显示到控制台 继续发送
		}
		else
		{
			num++;
		}
	}
}

/***********************************
 解析并处理用户请求
***********************************/
void handle_req(char* request, int client_sock)
{
	char command[BUFSIZ];					// 保存解析到的命令字段 GET PUT
	char arguments[BUFSIZ];					// 保存解析到的请求的文件

	/*
	* 在用户请求前加上当前目录符号
	*/
	strcpy(arguments, "./");				// 注意该符号在不同操作系统的区别
	
	printf("request = %s\n", request);

	/*
	* 解析请求
	*/
	if (sscanf(request, "%s /%s", command, arguments + 2) != 2)
	{
		return;								// 解析出错在返回
	}

	printf("handle_cmd:    %s\n",command);	// 向控制台输出此时的命令
	printf("handle_path:   %s\n",arguments);// 向控制台输出此时的请求路径

	if (strcmp(command, "GET") != 0)		// 请求命令格式是否正确
	{
		wrong_req(client_sock);
		return;
	}

	if (not_exit(arguments))				// 请求的文件是否存在
	{
		printf("not exit\n");
		file_not_found(arguments, client_sock);
		return;
	}

	send_file(arguments, client_sock);		// 命令格式及请求路径正确则发送数据

	return;
}

/*************************************
 该方法构造服务器端的SOCKET
 返回构造好的socket描述符
*************************************/
int make_server_socket()
{
	struct sockaddr_in server_addr;			// 服务器地址结构体
	int tempSockId;							// 临时存储socket描述符
	tempSockId = socket(AF_INET, SOCK_STREAM, 0);

	if (tempSockId == -1)					// 如果返回值为-1 则出错
	{
		return -1;
	}

	/*
	* 填充服务器连接信息
	*/
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(SERVER_PORT);
	server_addr.sin_addr.s_addr = inet_addr("10.2.3.51");  //本地地址
	memset(&(server_addr.sin_zero), '\0', 8);

	// 绑定服务如果出错 则返回-1
	if (bind(tempSockId, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)
	{
		printf("bind error!\n");
		return -1;
	}

	if (listen(tempSockId, BACKLOG) == -1 )	// 开始监听
	{
		printf("listen error!\n");
		return -1;
	}

	return tempSockId;						// 返回取得的SOCKET
}

/***********************
 主函数main()
 程序入口
***********************/
int main(int argc, char * argv[])
{
	printf("My web server started...\n");

	int server_socket;						// 服务器的socket
	int acc_socket;							// 接收到的用户连接的socket
	int sock_size = sizeof(struct sockaddr_in);
	struct sockaddr_in user_socket;			// 客户连接信息
	server_socket = make_server_socket();   // 创建服务器端的socket

	if (server_socket == -1)				// 创建socket出错
	{
		printf("Server exception!\n");
		exit(2);
	}
	
	printf("server_socket = %d\n", server_socket);

	/*
	* 主循环
	*/
	while (1)
	{
		acc_socket = accept(server_socket, (struct sockaddr *)&user_socket, &sock_size); // 接收连接

		// printf("acc_socket = %d\n", acc_socket);		// use test

		/*
		* 读取客户请求
		*/
		int numbytes;
		char buf[100];
		if ((numbytes = recv(acc_socket, buf, 99, 0)) == -1)
		{
			perror("recv");
			exit(1);
		}

		//printf("buf ... %s", buf);		// use test

		/*
		* 处理用户请求
		*/
		handle_req(buf, acc_socket);
	}
}


        以前就有发表过相关的文字《一个关于linux socket的简单例子》,也是属于文件传输的。好多个类似这样的例子,由于时间关系,并且并不是经常用,因此暂时先记录下来以备以后用时查找,研究。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值