linux网络通信并发程序设计(一)

在Linux网络编程中,一般建立在两端之间,服务器端和客户端。客户端是面向用户的应用,而服务器端要处理客户端所提出的请求。通常一个服务器要面向多个客户端,保证对每个客户端都能高效的处理,这时候需要并发操作。实现并发控制的方法有两个,一个是并发服务器,另一个是多路复用I/O,现在就给大家介绍一下这两种方法。

方法一:并发服务器

这个方法可以通过进程(线程)来实现,主要根据子进程(子线程)之间并行运行的特点。将对客户端请求的处理工作,交于子进程(子线程)来处理,达到一个服务器同时处理多个客户端的效果。

1、这是通过(子)进程来实现的。

<span style="font-size:14px;font-weight: normal;">------------------------- server.c -------------------------
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main(){
	int sockfd, newfd, r;
  	struct sockaddr_in myaddr;
  	struct sockaddr_in fromaddr;
  	socklen_t len = 16;
  	char buf[100] = {0};
  	pid_t pid;
  	sockfd = socket(AF_INET, SOCK_STREAM, 0);
  	
	myaddr.sin_family = AF_INET;
  	myaddr.sin_port = htons(5666);
  	myaddr.sin_addr.s_addr = inet_addr("192.168.80.128");

  	r = bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr));
  	if(listen(sockfd, 10) < 0){
    	perror("listen");
    	return -1;
  	}
  
  	while(1){
    	printf("the server is listenning..................\n");
    	newfd = accept(sockfd, &fromaddr, &len);
    	
    	if(newfd > 0){
    		printf("accept done! newfd = %d\n",newfd);
		}
    	pid = fork();
    	if(pid == 0){
      		while(1){
				r = recv(newfd, buf, 100, 0);
				if(r < 0){
	  				perror("recv")
      	  			break;
				}	
				printf("%d: %s\n", newfd, buf);
				bzero(buf, strlen(buf));
      		}
      		close(newfd);
      		bzero(&fromaddr, strlen(fromaddr));
			exit(0);
    	}else if(pid < 0)
      		exit(0);
  	}
}</span>
2、这是通过线程实现的

<pre name="code" class="cpp" style="font-weight: bold;"><span style="font-weight: normal;"><span style="font-size:14px;">------------------------- server.c -------------------------
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h></span></span>
#include <pthread.h>void *fun(void *p){int fd = *((int *)p);char buf[100] = {0};int r;printf("pthread fd = %d start\n", fd);while(1){r = recv(fd, buf, 100, 0);if(r <= 0){printf("客户端已退出 %d\n", fd);break;}printf("%d: %s\n", fd, buf);bzero(buf, strlen(buf));}close(fd);}int main(){int sockfd, newfd, r;struct sockaddr_in myaddr;struct sockaddr fromaddr;socklen_t len=16;char buf[100] = {0};pthread_t tid;sockfd = socket(AF_INET, SOCK_STREAM, 0);myaddr.sin_family = AF_INET;myaddr.sin_port = htons(5666);myaddr.sin_addr.s_addr = inet_addr(192.168.80.128);r = bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr));if(listen(sockfd, 10) < 0){perror("listen");return -1;}while(1){newfd = accept(sockfd, &fromaddr, &len);printf("newfd = %d \n", newfd);pthread_creat(&tid, NULL, fun, &newfd);}close(sockfd);}
 
 
<span style="font-size:18px;">注意:由于</span><span style="font-size:14px; color: rgb(51, 51, 51); font-family: arial, 宋体, sans-serif; line-height: 24px; text-indent: 28px;">pthread并非Linux系统的默认库,而是POSIX线程库。在Linux中将其作为一个库来使用,因此加上 -lpthread(或-pthread)以显式链接该库。</span>
<span style="font-size:14px; color: rgb(51, 51, 51); line-height: 24px; text-indent: 28px;"><span style="font-family:SimSun;">#gcc server_xian.c -o server_xian -pthread</span><span style="font-family:arial, 宋体, sans-serif;">
</span></span>

3、客户端代码相同,如下:
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(){

  int sockfd,r;
  char buf[100] = {0};
  struct sockaddr_in toaddr;
  sockfd = socket(AF_INET, SOCK_STREAM, 0); 
  printf("sockfd = %d\n", sockfd);

  toaddr.sin_family = AF_INET; 
  toaddr.sin_port = htons(5666); 
  toaddr.sin_addr.s_addr = inet_addr("192.168.80.128"); 

  r = connect(sockfd, (struct sockaddr *)&toaddr, sizeof(toaddr));
  if(r == -1){ perror("connect "); return -1; }
  printf("connect OK\n"); 
  while(1){ 
    scanf("%s", buf);
    send(sockfd, buf, strlen(buf), 0);
  }
  close(sockfd);
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值