首页 > 其他 > 详细

linux网络编程

时间:2014-02-26 23:12:39      阅读:548      评论:0      收藏:0      [点我收藏+]

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 int
typedef 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;
}
运行结果:
bubuko.com,布布扣

bubuko.com,布布扣

linux网络编程,布布扣,bubuko.com

linux网络编程

原文:http://blog.csdn.net/huangbo_embed/article/details/19925583

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!