懒大王感谢大家的关注和三连支持~
目录
前言
一、并发服务器
1.进程并发服务器
实例代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
// struct sockaddr_in client;
// int len = sizeof(client);
void *zhuanfa(void *arg)
{
int ret;
int fd = *(int *)arg;
char buf[1024];//接信息
char buf1[50] = "猖狂,北伐!";
while(1)
{
bzero(buf,sizeof(buf));
ret = recv(fd,buf,sizeof(buf),0);
if(0 == ret)
{
printf("客户%d离开了\n",fd);
close(fd);
return NULL;
}else
{
printf("客户%d:%s\n",fd,buf);
// printf("客户%d进来了,IP地址为%s,端口号为%d\n",fd,inet_ntoa(client.sin_addr),ntohs(client.sin_port));
send(fd,buf1,strlen(buf1),0);
}
}
return NULL;
}
int main(void)
{
//socket
int serfd = socket(AF_INET,SOCK_STREAM,0);
if(0>serfd)
{
perror("socket");
return -1;
}
//bind
struct sockaddr_in ser;//netinet/in.h
ser.sin_family = AF_INET;
ser.sin_port = htons(8888);
ser.sin_addr.s_addr = inet_addr("192.168.10.5");
if(bind(serfd,(struct sockaddr *)&ser,sizeof(ser))<0)
{
perror("bind");
return -1;
}
//listen
listen(serfd,8);
//accept
int cfd;
pthread_t a;
while(1)
{
//不断接受不同的客户端,并分配一个服务员给客户对接,在线程进行通信
cfd = accept(serfd,NULL,NULL);//accept保存客户信息到client
// pthread_create(&a,NULL,zhuanfa,&cfd);
// pthread_detach(a);
if(fork()==0)
{
zhuanfa(&cfd);
}
}
return 0;
}
2.线程并发服务器
实例代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
struct sockaddr_in client;
int len = sizeof(client);
void *zhuanfa(void *arg)
{
int ret;
int fd = *(int *)arg;
char buf[1024];//接信息
char buf1[50] = "注意绿色上网!";
while(1)
{
bzero(buf,sizeof(buf));
ret = recv(fd,buf,sizeof(buf),0);
if(0 == ret)
{
printf("客户%d离开了\n",fd);
close(fd);
return NULL;
}else
{
printf("客户%d:%s\n",fd,buf);
printf("客户%d进来了,IP地址为%s,端口号为%d\n",fd,inet_ntoa(client.sin_addr),ntohs(client.sin_port));
send(fd,buf1,strlen(buf1),0);
}
}
return NULL;
}
int main(void)
{
//socket
int serfd = socket(AF_INET,SOCK_STREAM,0);
if(0>serfd)
{
perror("socket");
return -1;
}
//bind
struct sockaddr_in ser;//netinet/in.h
ser.sin_family = AF_INET;
ser.sin_port = htons(8888);
ser.sin_addr.s_addr = inet_addr("192.168.10.5");
if(bind(serfd,(struct sockaddr *)&ser,sizeof(ser))<0)
{
perror("bind");
return -1;
}
//listen
listen(serfd,8);
//accept
int cfd;
pthread_t a;
while(1)
{
//不断接受不同的客户端,并分配一个服务员给客户对接,在线程进行通信
cfd = accept(serfd,(struct sockaddr *)&client,&len);//accept保存客户信息到client
pthread_create(&a,NULL,zhuanfa,&cfd);
pthread_detach(a);
}
return 0;
}
二、域通信
域通信TCP实例代码如下:
服务器:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
#include <sys/select.h>
int main(void)
{
//socket(变动)
int sockfd = socket(AF_UNIX,SOCK_STREAM,0);//注意AF_UNIX
if(0>sockfd)
{
perror("socket");
return -1;
}
//bind(变动)
struct sockaddr_un server;
server.sun_family = AF_UNIX;
strcpy(server.sun_path,"DJ");
bind(sockfd,(struct sockaddr *)&server,sizeof(server));
//listen
listen(sockfd,8);
//多路复用select
int max = 0;
int ret,cfd;//标志
fd_set rfds;//读集合
char buf[30];
while(1)
{
FD_ZERO(&rfds);
FD_SET(0,&rfds);
FD_SET(sockfd,&rfds);
max = sockfd;
if(cfd>sockfd)//第一遍还没连接,这个判断没有作用
{
max=cfd;
FD_SET(cfd,&rfds);
}
select(max+1,&rfds,NULL,NULL,NULL);
if(FD_ISSET(0,&rfds))
{
bzero(buf,sizeof(buf));
printf("0文件描述符触发\n");
scanf("%s",buf);
printf("键盘输入:%s\n",buf);
if(cfd>3)//说明有人连接,改变了cfd一开始的值
{
send(cfd,buf,strlen(buf),0);
}
}else if(FD_ISSET(sockfd,&rfds))
{
cfd = accept(sockfd,NULL,NULL);
if(0>cfd)
{
perror("accept");
return -1;
}
printf("有客户连接进来了!\n");
}else
{
bzero(buf,sizeof(buf));
ret = recv(cfd,buf,sizeof(buf),0);
if(0 == ret)
{
perror("recv");
return -1;
}else
{
printf("客户说:%s\n",buf);
}
}
}
return 0;
}
客户端:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
void *(recv_msg)(void *arg)
{
int ret;
int fd = *(int *)arg;
char buf[50];
while(1)
{
bzero(buf,sizeof(buf));
ret = recv(fd,buf,sizeof(buf),0);
if(0>ret)
{
perror("recv");
return NULL;
}else if(0 == ret)
{
printf("服务器离开了\n");
return NULL;
}else
printf("服务器说:%s\n",buf);
}
return NULL;
}
int main(int argc,char *argv[])
{
//变量区
int clifd,ret;
char buf[1024];
pthread_t pid;
//1>进行传参错误判断
if(argc<2)//你运行时输入的个数 ./x a b
{
printf("请输入<./可执行> <S_name> \n");
return -1;
}
//2>创建socket套接字
clifd = socket(AF_UNIX,SOCK_STREAM,0);
if(clifd<0)
{
perror("socket");
return -1;
}
printf("创建出的socket的值为%d\n",clifd);
//3>声明s套接字
struct sockaddr_un server;
server.sun_family = AF_UNIX;
strcpy(server.sun_path,(argv[1]));
#if 0
if(bind(clifd,(struct sockaddr *)&server,sizeof(server))<0)
{
perror("bind");
return -1;
}
//4>监听
if(listen(clifd,8)<0)
{
perror("listen");
return -1;
}
printf("监听已启动,保护服务器中^-^\n");
#endif
//5>主动连接服务器
if(connect(clifd,(struct sockaddr *)&server,sizeof(server))<0)
{
perror("connect");
return -1;
}
printf("成功连接!\n");
//开辟线程
pthread_create(&pid,NULL,recv_msg,&clifd);
pthread_detach(pid);
//6>收发数据
while(1)
{
bzero(buf,sizeof(buf));
scanf("%s",buf);
send(clifd,buf,strlen(buf),0);
}
//7>关闭套接字
close(clifd);
return 0;
}
补充说明:
三、广播与组播(UDP)
1.广播
实例代码如下:
sendto:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(0>sockfd)
{
perror("socket");
return -1;
}
//设置发送广播属性
int on = 1;//1>为生效值,0>不生效
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
struct sockaddr_in gb;
gb.sin_family = AF_INET;
gb.sin_port = htons(10086);
gb.sin_addr.s_addr = inet_addr("192.168.10.255");
#if 0
if(bind(sockfd,(struct sockaddr *)&gb,sizeof(gb))<0)
{
perror("bind");
return -1;
}
#endif
char buf[1024];
// int addrlen = sizeof(gb);
while(1)
{
bzero(buf,sizeof(buf));
scanf("%s",buf);
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&gb,sizeof(gb));
// printf("广播:%s\n",buf);
}
return 0;
}
recvfrom:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(0>sockfd)
{
perror("socket");
return -1;
}
struct sockaddr_in gb;
gb.sin_family = AF_INET;
gb.sin_port = htons(10086);
gb.sin_addr.s_addr = inet_addr("192.168.10.255");
if(bind(sockfd,(struct sockaddr *)&gb,sizeof(gb))<0)
{
perror("bind");
return -1;
}
char buf[1024];
int addrlen = sizeof(gb);
while(1)
{
bzero(buf,sizeof(buf));
recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&gb,&addrlen);
printf("广播:%s\n",buf);
}
return 0;
}
2.组播
实例代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{
//1.socket
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(0>sockfd)
{
perror("socket");
return -1;
}
//2.运行发送广播
int on = 1;//1>为生效值,0>不生效
setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&on,sizeof(on));
//3.声明组播地址
struct sockaddr_in zb;
zb.sin_family = AF_INET;
zb.sin_port = htons(9898);
zb.sin_addr.s_addr = inet_addr("233.233.233.233");
// if(bind(sockfd,(struct sockaddr *)&zb,sizeof(zb))<0)
// {
// perror("bind");
// return -1;
// }
//3.加入多播组
// struct ip_mreq zb;
// zb.imr_multiaddr.s_addr = inet_addr("233.233.233.233");
// zb.imr_interface.s_addr = inet_addr("192.168.10.5");
// setsockopt(sockfd,IPPROTO_IP,SO_ADD_MEMBERSHIP,&zb,sizeof(zb));
//4.接收数据
char buf[30];
// int len = sizeof(zb);
while(1)
{
bzero(buf,sizeof(buf));
scanf("%s",buf);
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&zb,sizeof(zb));
// printf("S:%s\n",buf);
}
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/un.h>
int main(void)
{
//1.socket
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
if(0>sockfd)
{
perror("socket");
return -1;
}
//2.bind组播地址
struct sockaddr_in zb;
zb.sin_family = AF_INET;
zb.sin_port = htons(9898);
zb.sin_addr.s_addr = inet_addr("233.233.233.233");
if(bind(sockfd,(struct sockaddr *)&zb,sizeof(zb))<0)
{
perror("bind");
return -1;
}
//3.加入多播组
struct ip_mreq db;
db.imr_multiaddr.s_addr = inet_addr("233.233.233.233");
db.imr_interface.s_addr = inet_addr("192.168.10.5");
setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&db,sizeof(db));
//4.接收数据
char buf[30];
int len = sizeof(zb);
while(1)
{
bzero(buf,sizeof(buf));
recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&zb,&len);
printf("S:%s\n",buf);
}
return 0;
}
四、图解如下