linux网络编程

来源:互联网 发布:sqlserver 复制表 编辑:程序博客网 时间:2024/06/05 16:41

1、基于TCP(面向连接)的socket编程,分为客户端和服务器端。

客户端的流程如下:

(1)创建套接字(socket)

(2)设置要连接的服务器的IP地址和端口信息

(3)向服务器发出连接请求(connect)

(4)和服务器端进行通信(send/recv或read/write)

(5)关闭套接字(close)

服务器端的流程如下:

(1)创建套接字(socket)

(2)将套接字绑定到一个本地地址和端口上(bind)

(3)将套接字设为监听模式,准备接收客户端请求(listen)

(4)等待客户请求到来;当请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept)

(5)用返回的套接字和客户端进行通信(send/recv或read/write)

(6)返回,等待另一个客户请求。

(7)关闭套接字。

2、服务器模型

1、循环服务器

2、并发服务器

3、I/O多路复用

3、事例代码

1、循环服务器

//server.c#include "server_c.h"int main(int argc, char const *argv[]){pid_t ser_fd;int i,max;if(-1 == (ser_fd=fork())){perror("fork");exit(-1);}if(ser_fd != 0){exit(0);}if(-1 == setsid()){perror("setsid");exit(-1);}if(-1 == chdir("/tmp")){perror("chdir");}umask(0);max = getdtablesize();for(i=0;i < max;i++){close(i);}int s_fd,c_fd;socklen_t len=sizeof(struct sockaddr_in); struct sockaddr_in server={0},client={0};bzero(&server,sizeof(server));if(-1 == (s_fd=(socket(AF_INET,SOCK_STREAM,0)))){perror("socket");exit(-1);} server.sin_family = AF_INET;server.sin_port = htons(8888);server.sin_addr.s_addr = inet_addr("0.0.0.0");if(-1 == bind(s_fd,(struct sockaddr*)&server,sizeof(server))){perror("bind");exit(-1);}if(-1 == listen(s_fd,MAXBACKLOG)){perror("listen");exit(-1);}while(1){bzero(&client,sizeof(client));if(-1 == (c_fd=accept(s_fd,(struct sockaddr*)&client,&len))){perror("accept");exit(-1);}calc(c_fd);close(c_fd);}return 0;}
2、循环服务器

//server.c#include "server_c.h"void fun(int sig){if(sig == SIGCHLD){waitpid(-1,NULL,0);}}int main(int argc, char const *argv[]){pid_t ser_fd;int i,max;if(-1 == (ser_fd=fork())){perror("fork");exit(-1);}if(ser_fd != 0){exit(0);}if(-1 == setsid()){perror("setsid");exit(-1);}if(-1 == chdir("/tmp")){perror("chdir");}umask(0);max = getdtablesize();for(i=0;i < max;i++){close(i);}int s_fd,c_fd;pid_t pid;socklen_t len=sizeof(struct sockaddr_in); struct sockaddr_in server={0},client={0};bzero(&server,sizeof(server));if(-1 == (s_fd=(socket(AF_INET,SOCK_STREAM,0)))){perror("socket");exit(-1);} server.sin_family = AF_INET;server.sin_port = htons(8888);server.sin_addr.s_addr = inet_addr("0.0.0.0");if(-1 == bind(s_fd,(struct sockaddr*)&server,sizeof(server))){perror("bind");exit(-1);}if(-1 == listen(s_fd,MAXBACKLOG)){perror("listen");exit(-1);}signal(SIGCHLD,fun);while(1){bzero(&client,sizeof(client));if(-1 == (c_fd=accept(s_fd,(struct sockaddr*)&client,&len))){perror("accept");exit(-1);}if(-1 == (pid=fork())){perror("fork");exit(-1);}if(0 == pid){calc(c_fd);close(c_fd);exit(0);}else{close(c_fd);}}return 0;}
3、I/O多路复用
//server.c#include "server_c.h"int main(int argc, char const *argv[]){pid_t ser_fd;int i,max;if(-1 == (ser_fd=fork())){perror("fork");exit(-1);}if(ser_fd != 0){exit(0);}if(-1 == setsid()){perror("setsid");exit(-1);}if(-1 == chdir("/tmp")){perror("chdir");}umask(0);max = getdtablesize();for(i=0;i < max;i++){close(i);}int s_fd,c_fd;pid_t pid;socklen_t len=sizeof(struct sockaddr_in); struct sockaddr_in server={0},client={0};bzero(&server,sizeof(server));if(-1 == (s_fd=(socket(AF_INET,SOCK_STREAM,0)))){perror("socket");exit(-1);} server.sin_family = AF_INET;server.sin_port = htons(8888);server.sin_addr.s_addr = inet_addr("0.0.0.0");if(-1 == bind(s_fd,(struct sockaddr*)&server,sizeof(server))){perror("bind");exit(-1);}if(-1 == listen(s_fd,MAXBACKLOG)) {perror("listen");exit(-1);}    fd_set reads;    FD_ZERO(&reads);    FD_SET(s_fd,&reads);    fd_set tem_fds = reads;    int max_fd = s_fd;    while(1){    reads = tem_fds;    if(-1 == select(max_fd+1,&reads,NULL,NULL,NULL)){    perror("select");    exit(-1);    }    if(FD_ISSET(s_fd,&reads)){    bzero(&client,sizeof(client));    if(-1 == (c_fd=accept(s_fd,(struct sockaddr*)&client,&len))){perror("accept");exit(-1);}FD_SET(c_fd,&tem_fds);max_fd = (max_fd > c_fd ? max_fd : c_fd);    }    else{    int i;    for (i = 0; i < max_fd+1; ++i)    {    if(FD_ISSET(i,&reads)&& i != s_fd){    calc(i);    }    }    }}return 0;}
4、其他相关程序

//server_c.c#include "server_c.h"void creat_stack(TSq *t){*t=NULL;}int  empty_stack(TSq t){return t==NULL;}int  get_stack_top(TSq t){if(empty_stack(t)){printf("Stack is empty!\n");exit(0);}return t->data;}void push(TSq *t,data_t data){TSq q;q=(TSq)malloc(sizeof(Sq));q->data=data;q->next=*t;*t=q;}int  pop(TSq *t){data_t data;if(empty_stack(*t)){printf("Stack is empty!\n");return;}data=(*t)->data;*t=(*t)->next;return data;}void display(TSq t){TSq p;p=t;while(p!=NULL){printf("%c  ",p->data);p=p->next;}}void calculate_arith(char *str,char *result){TSq record,symbol;char *p;int i,a,b,c1;creat_stack(&record);creat_stack(&symbol);for(p=str;*p!='\0';p++){c1 = *p;if(*p >= '0' && *p <= '9'){c1=atoi(p);while(*(++p)>='0' && *p <= '9');p--;}switch(c1){case '+':{int a,b,c;if(empty_stack(symbol)){push(&symbol,c1);}else{while(!empty_stack(symbol)&&(c=get_stack_top(symbol))!='('){c=pop(&symbol);switch(c){case '+':{a=pop(&record);b=pop(&record);push(&record,a+b);}break;case '-':{a=pop(&record);b=pop(&record);push(&record,b-a);}break;case '*':{a=pop(&record);b=pop(&record);push(&record,a*b);}break;case '/':{a=pop(&record);b=pop(&record);push(&record,b/a);}break;default:{printf("%c is Unknow symbol!\n",c);exit(-1);}break;}}push(&symbol,c1);}}break;case '-':{int a,b,c;if(empty_stack(symbol)){push(&symbol,c1);}else{while(!empty_stack(symbol)&&(c=get_stack_top(symbol))!='('){c=pop(&symbol);switch(c){case '+':{a=pop(&record);b=pop(&record);push(&record,a+b);}break;case '-':{a=pop(&record);b=pop(&record);push(&record,b-a);}break;case '*':{a=pop(&record);b=pop(&record);push(&record,a*b);}break;case '/':{a=pop(&record);b=pop(&record);push(&record,b/a);}break;default:{printf("%c is Unknow symbol!\n",c);exit(-1);}break;}}push(&symbol,c1);}}break;case '*':{int a,b,c;if(empty_stack(symbol)){push(&symbol,c1);}else{while(!empty_stack(symbol)&&(c=get_stack_top(symbol))=='*'&&(c=get_stack_top(symbol))=='/'){c=pop(&symbol);switch(c){case '*':{a=pop(&record);b=pop(&record);push(&record,a*b);}break;case '/':{a=pop(&record);b=pop(&record);push(&record,b/a);}break;default:{printf("%c is Unknow symbol!\n",c);exit(-1);}break;}}push(&symbol,c1);}}break;case '/':{int a,b,c;if(empty_stack(symbol)){push(&symbol,c1);}else{while(!empty_stack(symbol)&&(c=get_stack_top(symbol))=='*'&&(c=get_stack_top(symbol))=='/'){c=pop(&symbol);switch(c){case '*':{a=pop(&record);b=pop(&record);push(&record,a*b);}break;case '/':{a=pop(&record);b=pop(&record);push(&record,b/a);}break;default:{printf("%c is Unknow symbol!\n",c);exit(-1);}break;}}push(&symbol,c1);}}break;case '(':{push(&symbol,'(');}break;case ')':{int a,b,c;while((c=pop(&symbol))!='('){switch(c){case '+':{a=pop(&record);b=pop(&record);push(&record,a+b);}break;case '-':{a=pop(&record);b=pop(&record);push(&record,b-a);}break;case '*':{a=pop(&record);b=pop(&record);push(&record,a*b);}break;case '/':{a=pop(&record);b=pop(&record);push(&record,b/a);}break;default:{printf("%c is Unknow symbol!\n",c);exit(-1);}break;}}}break;default:{push(&record,c1);} break;}}while(!empty_stack(symbol)){c1=pop(&symbol);switch(c1){case '+':{a=pop(&record);b=pop(&record);push(&record,a+b);}break;case '-':{a=pop(&record);b=pop(&record);push(&record,b-a);}break;case '*':{a=pop(&record);b=pop(&record);push(&record,a*b);}break;case '/':{a=pop(&record);b=pop(&record);push(&record,b/a);}break;default:{printf("%c is Unknow symbol!\n",c1);exit(-1);}break;}}sprintf(result,"计算结果为:\n %s = %d\n",str,pop(&record));}void calc(int c_fd){char buf[200],result[200];while(1){bzero(buf,200);bzero(result,50);read(c_fd,buf,200);if(0 == strncmp(buf,"quit",4)){break;}calculate_arith(buf,result);write(c_fd,result,200);}}
//server_c.h#ifndef _SERVER_C_H_#define _SERVER_C_H_#include <stdio.h>#include <strings.h>#include <sys/types.h>        #include <sys/socket.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <time.h>#include <sys/wait.h>#define MAXBACKLOG 100#define data_t inttypedef struct stack{/* data */int data;struct stack *next;}Sq,*TSq;void creat_stack(TSq *t);int  empty_stack(TSq t);int  get_stack_top(TSq t);void push(TSq *t,data_t data);int  pop(TSq *t);void display(TSq t);void calculate_arith(char *str,char *result);void calc(int c_fd);#endif
5、客户端程序
//client.c#include <stdio.h>#include <strings.h>#include <sys/types.h>        #include <sys/socket.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <netinet/in.h>#include <arpa/inet.h>#include <time.h>#include <sys/wait.h>#include <pthread.h>
int main(int argc, char const *argv[]){if(3 != argc){printf("Usage: %s <IP> <Port>\n",argv[0]);exit(-1);}int c_fd;char buf[200];struct sockaddr_in server;bzero(&server,sizeof(struct sockaddr_in));if(-1 == (c_fd=(socket(AF_INET,SOCK_STREAM,0)))){perror("socket");exit(-1);} server.sin_family = AF_INET;server.sin_port = htons(atoi(argv[2]));server.sin_addr.s_addr = inet_addr(argv[1]);if(-1 == connect(c_fd,(struct sockaddr*)&server,sizeof(struct sockaddr_in))){perror("connect");exit(-1);}while(1){bzero(buf,200);printf("输入数学表达式:");fflush(stdout);gets(buf);write(c_fd,buf,200);if(0 == strncmp(buf,"quit",4)){printf("quit\n");exit(0);}bzero(buf,200);read(c_fd,buf,200);printf("%s",buf);}return 0;}
6、多线程并发服务器
//server.c#include "server_c.h"void* compute(void *arg){int c_fd = *((int *)arg);//printf("pthread %d created!\n");calc(c_fd);close(c_fd);pthread_exit(NULL);}int main(int argc, char const *argv[]){pid_t ser_fd;int i,max;if(-1 == (ser_fd=fork())){perror("fork");exit(-1);}if(ser_fd != 0){exit(0);}if(-1 == setsid()){perror("setsid");exit(-1);}if(-1 == chdir("/tmp")){perror("chdir");}umask(0);max = getdtablesize();for(i=0;i < max;i++){close(i);}int s_fd,c_fd;pid_t pid;socklen_t len=sizeof(struct sockaddr_in); struct sockaddr_in server={0},client={0};bzero(&server,sizeof(server));if(-1 == (s_fd=(socket(AF_INET,SOCK_STREAM,0)))){perror("socket");exit(-1);} server.sin_family = AF_INET;server.sin_port = htons(8888);server.sin_addr.s_addr = inet_addr("0.0.0.0");if(-1 == bind(s_fd,(struct sockaddr*)&server,sizeof(server))){perror("bind");exit(-1);}if(-1 == listen(s_fd,MAXBACKLOG)){perror("listen");exit(-1);}while(1){bzero(&client,sizeof(client));if(-1 == (c_fd=accept(s_fd,(struct sockaddr*)&client,&len))){perror("accept");exit(-1);}pthread_t thread;pthread_create(&thread,NULL,compute,&c_fd);}return 0;}
运行结果:

0 0
原创粉丝点击