1.tcp并发服务器,进程版
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/wait.h>
#include<signal.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__:",__LINE__);\
perror(msg);\
}while(0)
typedef void (*sighandler_t)(int);
int rcv_msg(int newfd,struct sockaddr_in cin);
void handler(int sig)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
sighandler_t s=signal(17,handler);
if(SIG_ERR==s)
{
ERR_MSG("signal");
return -1;
}
//创建流式套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
//允许端口快速重用
int reuse=1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
//填充ip和端口信息到结构体中
struct sockaddr_in sin;
sin.sin_family = AF_INET; //地址族必须是AF_INET
sin.sin_port = htons(8888); //端口号的网络字节序(1024~49151)
sin.sin_addr.s_addr = inet_addr("192.168.31.109"); //ubuntu 的本机地址,用桥接
//绑定服务器的ip地址和端口
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd,128)<0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
//获取新的文件描述符,该描述符用于通信
struct sockaddr_in a;
int size=sizeof(a);
int newfd;
while(1)
{
newfd = accept(sfd,(struct sockaddr*)&a,&size);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
printf("ip=%s newfd=%d\n",inet_ntoa(a.sin_addr),newfd);
pid_t pid=fork();
if(pid==0)
{
close(sfd);
rcv_msg(newfd,a);
close(newfd);
return 0;
}
else if(pid>0)
{
}
else
{
ERR_MSG("fork");
return -1;
}
close(newfd);
}
close(sfd);
return 0;
}
int rcv_msg(int newfd,struct sockaddr_in cin)
{
char buf[128]="";
ssize_t res;
while(1)
{
bzero(buf,sizeof(buf));
//接收
res=recv(newfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("recv");
return -1;
}
if(res==0)
{
printf("%d对端关闭\n",ntohs(cin.sin_port));
break;
}
printf("%d客户端:%s\n",ntohs(cin.sin_port),buf);
//发送
strcat(buf,"!!!");
res=send(newfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("send");
return -1;
}
}
}
2.tcp并发服务器,线程版
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/wait.h>
#include<pthread.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__:",__LINE__);\
perror(msg);\
}while(0)
typedef struct
{
int newfd;
struct sockaddr_in cin;
}mass;
void* rcv_msg(void *arg);
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
//允许端口快速重用
int reuse=1;
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
//填充ip和端口信息到结构体中
struct sockaddr_in sin;
sin.sin_family = AF_INET; //地址族必须是AF_INET
sin.sin_port = htons(8888); //端口号的网络字节序(1024~49151)
sin.sin_addr.s_addr = inet_addr("192.168.31.109"); //ubuntu 的本机地址,用桥接
//绑定服务器的ip地址和端口
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd,128)<0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
//获取新的文件描述符,该描述符用于通信
struct sockaddr_in a;
int size=sizeof(a);
int newfd;
pthread_t tid;
mass info;
while(1)
{
newfd = accept(sfd,(struct sockaddr*)&a,&size);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
printf("ip=%s newfd=%d\n",inet_ntoa(a.sin_addr),newfd);
info.newfd=newfd;
info.cin=a;
pthread_create(&tid,NULL,rcv_msg,(void*)&info);
pthread_detach(tid);
}
close(sfd);
return 0;
}
void* rcv_msg(void *arg)
{
mass* info=(mass*)arg;
int newfd=info->newfd;
struct sockaddr_in cin=info->cin;
char buf[128]="";
ssize_t res;
while(1)
{
bzero(buf,sizeof(buf));
//接收
res=recv(newfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("recv");
return NULL;
}
if(res==0)
{
printf("%d对端关闭\n",ntohs(cin.sin_port));
close(newfd);
break;
}
printf("%d客户端:%s\n",ntohs(cin.sin_port),buf);
//发送
strcat(buf,"!!!");
res=send(newfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("send");
return NULL;
}
}
}
3.域套接字-tcp版
服务器端
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/wait.h>
#include<pthread.h>
#include<sys/un.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__:",__LINE__);\
perror(msg);\
}while(0)
typedef struct
{
int newfd;
struct sockaddr_un cun;
}mass;
void* rcv_msg(void *arg);
int main(int argc, const char *argv[])
{
int sfd=socket(AF_UNIX,SOCK_STREAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path,"./unix");
if(access(sun.sun_path,F_OK)==0)
{
if(unlink(sun.sun_path)<0)
{
ERR_MSG("unlink");
return -1;
}
}
if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd,128)<0)
{
ERR_MSG("listen");
return -1;
}
printf("listen success\n");
//获取新的文件描述符,该描述符用于通信
struct sockaddr_un cun;
int size=sizeof(cun);
int newfd;
pthread_t tid;
mass info;
while(1)
{
newfd = accept(sfd,(struct sockaddr*)&cun,&size);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
printf("newfd=%d\n",newfd);
info.newfd=newfd;
info.cun=cun;
pthread_create(&tid,NULL,rcv_msg,(void*)&info);
pthread_detach(tid);
}
close(sfd);
return 0;
}
void* rcv_msg(void *arg)
{
mass* info=(mass*)arg;
int newfd=info->newfd;
struct sockaddr_un cun=info->cun;
char buf[128]="";
ssize_t res;
while(1)
{
bzero(buf,sizeof(buf));
//接收
res=recv(newfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("recv");
return NULL;
}
if(res==0)
{
printf("对端关闭\n");
close(newfd);
break;
}
printf("客户端:%s\n",buf);
//发送
strcat(buf,"!!!");
res=send(newfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("send");
return NULL;
}
}
}
4.域套接字-tcp版
客户端
#include<sys/socket.h>
#include<sys/types.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<arpa/inet.h>
#include<sys/un.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__:",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
//创建流式套接字
int sfd=socket(AF_UNIX,SOCK_STREAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
//填充ip和端口信息到结构体中(服务器的)
struct sockaddr_un sun;
sun.sun_family = AF_UNIX;
strcpy(sun.sun_path,"./unix");
//connect连接服务器
if(connect(sfd,(struct sockaddr*)&sun,sizeof(sun))<0)
{
ERR_MSG("connect");
return -1;
}
printf("connect success\n");
char buf[128]="";
ssize_t res;
while(1)
{
//发送
bzero(buf,sizeof(buf));
printf("请输入>>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]=0;
res=send(sfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("send");
return -1;
}
bzero(buf,sizeof(buf));
//接收
res=recv(sfd,buf,sizeof(buf),0);
if(res<0)
{
ERR_MSG("recv");
return -1;
}
if(res==0)
{
printf("对端关闭\n");
break;
}
printf("服务器:%s\n",buf);
}
close(sfd);
return 0;
}
5.域套接字-udp
服务器
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include<sys/un.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
int sfd=socket(AF_UNIX,SOCK_DGRAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
if(access("./unix",F_OK)==0)
{
if(unlink("./unix")<0)
{
ERR_MSG("unlink");
return -1;
}
}
struct sockaddr_un sun;
sun.sun_family=AF_UNIX;
strcpy(sun.sun_path,"./unix");
if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))<0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
char buf[128]="";
ssize_t res=0;
struct sockaddr_un cun;
socklen_t size=sizeof(cun);
while(1)
{
bzero(buf,sizeof(buf));
res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,&size);
if(res<0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s]:%s\n",cun.sun_path,buf);
strcat(buf,"!!!");
if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&cun,sizeof(cun))<0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
}
close(sfd);
return 0;
}
6.域套接字-udp
客户端
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
#include<unistd.h>
#include<sys/un.h>
#define ERR_MSG(msg) do{\
fprintf(stderr,"__%d__",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
int sfd=socket(AF_UNIX,SOCK_DGRAM,0);
if(sfd<0)
{
ERR_MSG("socket");
return -1;
}
if(access("./unix2",F_OK)==0)
{
if(unlink("./unix2")<0)
{
ERR_MSG("unlink");
return -1;
}
}
struct sockaddr_un cun;
cun.sun_family=AF_UNIX;
strcpy(cun.sun_path,"./unix2");
if(bind(sfd,(struct sockaddr*)&cun,sizeof(cun))<0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
struct sockaddr_un sun;
sun.sun_family=AF_UNIX;
strcpy(sun.sun_path,"./unix");
char buf[128]="";
ssize_t res=0;
struct sockaddr_un rcv;
socklen_t size=sizeof(rcv);
while(1)
{
bzero(buf,sizeof(buf));
printf("请输入>>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1]=0;
if(sendto(sfd,buf,sizeof(buf),0,(struct sockaddr*)&sun,sizeof(sun))<0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
bzero(buf,sizeof(buf));
res=recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&rcv,&size);
if(res<0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("[%s]:%s\n",rcv.sun_path,buf);
}
close(sfd);
return 0;
}