单进程socket的服务器/客户端模型
2011-11-30 11:27
531 查看
1.tcp.h:头文件
2.socklib.c:基本的socket模型的实现函数
3.server.c:服务器端的模型
4.client.c:客户端的模型
5.process_request.c:处理客户端的请求
6.connect_server.c:与服务端进行通信
1.tcp.h:头文件
2.socklib.c:基本的socket模型的实现函数
3.server.c:服务器端的模型
4.client.c:客户端的模型
5.process_request.c:处理客户端的请求
6.connect_server.c:与服务端进行通信
2.socklib.c:基本的socket模型的实现函数
3.server.c:服务器端的模型
4.client.c:客户端的模型
5.process_request.c:处理客户端的请求
6.connect_server.c:与服务端进行通信
1.tcp.h:头文件
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> #include <time.h> #include <sys/socket.h> #include <sys/types.h> #include <strings.h> #include <arpa/inet.h> #include <signal.h> #include <sys/time.h> #include <sys/wait.h> #include <errno.h> #define IPSERV "127.0.0.1" #define PORT 13000 #define BACKLOG 1 #define oops(msg) {perror(msg);exit(1);} extern int errno;
2.socklib.c:基本的socket模型的实现函数
#include "tcp.h" //函数声明 int make_server_socket_q(int,int); /* * 输入:端口号 * */ int make_server_socket(int port){ return make_server_socket_q(port,BACKLOG); } int make_server_socket_q(int port,int backlog){ // build our address struct sockaddr_in serv; int sockfd; // get a socket sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd<0) oops("socket"); // build address struct /* clear out struct */ bzero((void *)&serv,sizeof(serv)); /* fill in addr family */ serv.sin_family = AF_INET; /* fill in ip address */ serv.sin_addr.s_addr = inet_addr(IPSERV); /* fill in socket port */ serv.sin_port = htons(port); // bind the address information to the socket if(bind(sockfd,(struct sockaddr *)&serv,sizeof(serv))<0) oops("bind"); // waiting for the client request if(listen(sockfd,backlog)<0) oops("listen"); return sockfd; } int connect_to_server(char *host,int port){ // build our address struct sockaddr_in serv; int sockfd; // get a socket sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd < 0) oops("socket"); // build address struct bzero((void *)&serv,sizeof(serv)); serv.sin_family = AF_INET; serv.sin_addr.s_addr = inet_addr(host); serv.sin_port = htons(port); // connect to server if(connect(sockfd,(struct sockaddr *)&serv,sizeof(serv))<0) oops("connect"); return sockfd; }
3.server.c:服务器端的模型
#include "tcp.h" void child_waiter(int); /* * 标准的服务器处理模型 * * * 程序运行到信号处理函数跳转时中断accept。 * accept被中断时,返回-1,设置errno=EINTR,会跳出主循环 * if(fd<0){ * if(errno == EINTR) * continue; * else * oops("accept"); *} */ int main(int ac,char *av[]){ // the socket int sockfd; int fd; // get a socket which is listening sockfd = make_server_socket(PORT); if(sockfd == -1) exit(1); // deal with signal of SIGCHLD /* * when the child exit or be out, * kernel will send a signal——SIGCHLD to parent * 默认情况下SIGCHLD会被忽略 * * 僵尸进程会在什么时候产生 * 子进程结束,但是他的父进程没有等待(wait/waitpid) * 该子进程会变成僵尸进程 * 可是如果父进程已经提前结束 * 该子进程会变成孤儿进程,被init接管 * * 为了防止子进程成为僵尸进程,处理SIGCHLD信号 * 调用wait(NULL)来处理 * */ signal(SIGCHLD,child_waiter); // the connect request is coming while(1){ // take the connection fd = accept(sockfd,NULL,NULL); if(fd<0){ if(errno == EINTR) continue; else oops("accept"); } // connect with the client process_request(fd); // close the socket close(fd); } close(sockfd); } /* * 可是呢,调用wait(NULL)来处理会出现问题 * 如果多个子进程几乎同时退出 * 最先到到达的信号会导致父进程跳转到处理函数中 * 然后父进程调用wait将子进程从进程表中删除 * 可是,其他到来的信号怎么办呢 * 我们知道,信号是没有缓存机制的 * 第二个到来的信号被阻塞 * 第三个到来的信号会丢失,以后的依次类推 * 信号处理函数只调用wait一次, * 可是后来到达的信号没被处理,子进程会变成僵尸进程 * * 解决方法:在处理函数中, * 调用wait足够多的次数去清除所有的子进程 * waitpid提供了wait函数超集的功能 * 参数1:表示要等待的进程ID,-1,表示等待所有的子进程 * 参数2:指向整型值的指针,用来获取子进程状态 * 在未来的改版中,会根据这个参数来跟踪服务器信息 * 参数3:选项,WNOHANG高速waitpid若没有僵尸进程,则不必等待 * * 该循环直到所有退出的子进程都被等待才停止。 * 即使多个子进程同时退出并产生SIGCHLD,所有信号都会被处理。 * */ void child_waiter(int signum){ while(waitpid(-1,NULL,WNOHANG)>0); }
4.client.c:客户端的模型
#include "tcp.h" int main(){ int sockfd; sockfd = connect_to_server(IPSERV,PORT); if(sockfd == -1) oops("sockfd"); talk_with_server(sockfd); close(sockfd); }
5.process_request.c:处理客户端的请求
6.connect_server.c:与服务端进行通信
talk_with_server(int fd){ talk_with_server_v1(fd); } process_request(int fd){ process_request_v1(fd); }
相关文章推荐
- socket的服务器/客户端模型——时间服务器的版本演进
- linux局域网通讯源码(服务器多路复用和客户端多进程模式)(socket)服务器端
- linux局域网通讯源码(服务器多路复用和客户端多进程模式)(socket)客户端
- 多进程socket服务器防止僵尸进程 模型
- PHP-Websockets 上传文件2 优化支持php socket客户端和websocket连接websocket服务器 以守护进程方式运行编码
- Android基于客户端和服务器的Socket编程例子之Socket基础通讯--socket模型使用
- linux-socket tcp客户端服务器编程模型及代码详解
- linux socket 服务器与客户端多进程通信
- 关于socket应用:一个不断监听一个进程的服务器以及发送信息的客户端 TCP的三次握手和四次挥手
- Socket编程服务器和客户端(多个客户端可以同时连接一个服务器的同一端口)
- [再加工]XMLSocket(服务器+客户端)代码,包含解决中文问题
- socket编程-客户端向服务器发送字符串,传文件
- 网络编程(5)—— 基于Linux系统的UDP协议socket服务器和客户端
- 简单socket服务(二)实现多客户端向服务器发送数据
- java基础回顾3 Socket 一次完整的服务器客户端交互
- Android客户端,PC服务器,Socket连接所遇到的问题
- 多线程Socket编程实现服务器与客户端的连接
- 简单socket服务器客户端
- Linux网络编程[UDP客户端服务器的编程模型]
- 网络 客户端 多种方法 建立与服务端的连接 接口:服务器名,IP socket connect