Linux网络编程——服务器与客户端
2019-08-19 20:31
1461 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yiluo9918/article/details/99546916
文章目录
1 单连接C/S
简单实现单连接的服务器与客户端,服务器处理客户端的字符为大写返回给客户端
- 服务器端
#include <stdio.h> #include <unistd.h> #include <sys/socket.h> #include <stdlib.h> #include <ctype.h> #include <arpa/inet.h> #define SERV_PORT 6666 #define SERV_IP "127.0.0.1" int main() { int lfd,cfd; char buf[BUFSIZ],clie_IP[BUFSIZ]; int n; struct sockaddr_in serv_addr, clie_addr; socklen_t clie_addr_len; /*创建一个socket 指定IPv4协议族 TCP协议*/ lfd = socket(AF_INET, SOCK_STREAM, 0); /*初始化一个地址结构 man 7 ip 查看对应信息*/ bzero(&serv_addr, sizeof(serv_addr)); //将整个结构体清零 serv_addr.sin_family = AF_INET; //选择协议族为IPv4 serv_addr.sin_port = htons(SERV_PORT); //绑定端口号 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY这个宏可以自动转换为本地有效的IP /*绑定服务器地址结构*/ bind(lfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)); listen(lfd, 128); //同一时刻允许向服务器发起链接请求的数量 printf("wait for client connect ...\n"); clie_addr_len = sizeof(clie_addr);/*获取客户端地址结构大小*/ /*参数1是sfd; 参2传出参数, 参3传入传出参数, 全部是client端的参数*/ cfd = accept(lfd, (struct sockaddr *)&clie_addr, &clie_addr_len); printf("client IP:%s\tport:%d\n", inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)), ntohs(clie_addr.sin_port)); while(1){ /*读取客户端发送数据*/ n = read(cfd, buf, sizeof(buf)); //小写转大写发送给客户端 for(i=0;i<n;i++) buf[i] = toupper(buf[i]); write(cfd, buf,n); } close(lfd); close(cfd); return 0; }
- 客户端
client.c #include <stdio.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #define SERV_IP "127.0.0.1" #define SERV_PORT 6666 int main() { int sfd,serv_addr_len,cfd; char buf[BUFSIZ]; int n; sfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in serv_addr;//服务器IP+port bzero(&serv_addr, sizeof(serv_addr));//清零 serv_addr.sin_family = AF_INET; inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);//IP字符串转换为网络字节序 参3:传出参数 serv_addr.sin_port = htons(SERV_PORT);//端口号转网络字节序 connect(sfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr)); while(1){ fgets(buf, sizeof(buf), stdin);/*从标准输入获取数据*/ write(sfd, buf, strlen(buf));/*将数据写给服务器*/ len = read(sfd, buf, sizeof(buf));/*从服务器读回转换后数据*/ write(STDOUT_FILENO, buf,len); /*写至标准输出*/ } close(sfd); return 0; }
2 多进程并发C/S
- 服务器端(多进程并发)
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h> #include <strings.h> #include <ctype.h> #define SERV_PORT 8888 void wait_child(int signo){ while(waitpid(0,NULL,WNOHANG)>0);//子进程回收 return ; } int main() { pid_t pid; int lfd,cfd; struct sockaddr_in serv_addr,clie_addr; socklen_t clie_addr_len; char buf[BUFSIZ],clie_IP[BUFSIZ]; int n,i; lfd = socket(AF_INET, SOCK_STREAM,0); bzero(&serv_addr, sizeof(serv_addr));// 清零 serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(SERV_PORT); serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); //inet_pton(AF_INET,"192.168.43.1",serv_addr.sin_addr.s_addr); bind(lfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr)); listen(lfd,128); while(1){//接活,处理新到来的连接 clie_addr_len = sizeof(clie_addr); cfd = accept(lfd, (struct sockaddr *)&clie_addr, &clie_addr_len); printf("client IP:%s, port:%d\n", inet_pton(AF_INET,&clie_addr.sin_addr.s_addr, clie_IP, sizrof(clie_IP)), ntohs(clie_addr.sin_port) ) pid = fork(); if(pid<0){ perror("fork error"); exit(); }else if(pid==0){ //子进程 close(lfd); break; }else{ close(cfd); signal(SIGCHLD,wait_child);//处理僵尸进程,子进程 } } if(pid==0){ //子进程处理连接的数据 while(1){ n = read(cfd,buf,sizeof(buf)); if(n==0){ //client closed close(cfd); return 0; }else if(n==-1){ perror("read error"); exit(1); }else{ for(i=0;i<n;i++) buf[i] = toupper(buf[i]); write(cfd,buf,n); write(STDOUT_FILENO,buf,n); } } } return 0; }
3 多线程并发
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h> #include <strings.h> #include <ctype.h> #define MAXLINE 8192 #define SERV_PORT 8000 struct s_info{ struct sockaddr_in cliaddr; int connfd; } void *do_work(void *arg){ int n,i; struct s_info *ts = (struct s_info*)arg; char buf[MAXLINE]; char str[INET_ADDRSTRLEN]; //define INET_ADDRSTRLEN 16 while(1){ n = read(ts->connfd,buf,MAXLINE); if(n==0){ printf("the client %d closed...\n",ts->connfd); break; } printf("reveived from %s at PORT %d\n", inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)), ntohs((*ts).cliaddr.sin_port)); for(i=0;i<n;i++) buf[i] = toupper(buf[i]); write(STDOUT_FILENO,buf,n); write(ts->connfd,buf,n); } close(ts->connfd); return (void*)0; } int main() { struct sockaddr_in serv_addr, clie_addr; socklen_t clie_addr_len; int listenfd,connfd; pthread_t tid; struct s_info ts[256]; int i=0; listenfd = socket(AF_INET,SOCK_STREAM, 0); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(SERV_PORT); bind(listenfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr)); listen(listenfd,128); printf("Accepting client connet ...\n"); while(1){ clie_addr_len = sizeof(clie_addr); connfd = accept(listenfd,(struct sockaddr *)&clie_addr, &clie_addr_len);//阻塞监听客户端请求 ts[i].cliaddr = clie_addr; ts[i].connfd = connfd; /*达到线程最大数时,pthread_create出错处理,增加服务器稳定性 */ pthread_create(&tid,NULL,do_work,(void*)&ts[i]); pthread_detach(tid); //子线程分离,防止僵尸线程产生 i++;//统计是第几个线程 } return 0; }
相关文章推荐
- Linux网络编程:客户端/服务器的简单实现
- Linux下网络socket编程——实现服务器(select)与多个客户端通信
- Linux下简单的网络编程笔记(模拟简单的服务器与客户端的通信 1-服务器端)
- 【Linux网络编程】基于TCP协议 I/O多路转接(select) 的高性能回显服务器客户端模型
- Linux网络编程 3 - 简单的Tcp服务器和客户端编程
- linux网络编程--服务器客户端(TCP实现)
- Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
- Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
- Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
- Linux 网络编程基础(一) ---------------客户端/服务器的简单实现
- Linux 网络编程基础---------------客户端/服务器的简单实现
- 【Linux网络编程实例】实例二:利用TCP协议进行客户端与服务器通信
- Linux网络编程-简单的客户端和服务器通讯程序开发入门(2)
- linux 网络编程:客户端与服务器通过TCP协议相互通信
- linux 网络编程:客户端与服务器通过TCP协议相互通信 + UDP
- Linux下网络编程之自定义协议进行并发多客户端与服务器的通信(多进程处理并发)不足占用资源太多
- Linux 网络编程实现TCP协议下的服务器客户端通信
- Linux网络编程 之 TCP 多线程的服务器和客户端同时收发数据
- 【Linux网络编程】基于TCP多进程(fork)版本客户端/服务器
- Linux网络编程[UDP客户端服务器的编程模型]