多任务并发服务器
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <stdlib.h>
#define IP "192.168.31.197"
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__", __LINE__);\
perror(msg);\
}while(0)
typedef void(*sighandler_t)(int);
int rcv_cli_msg(int newfd, struct sockaddr_in cin);
void handler(int sig)
{
while(waitpid(-1, NULL, WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
//捕获17号信号,用信号的方式回收僵尸进程
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;
}
printf("允许端口快速重用设置成功\n");
//填充ip和端口到地址信息集团构体中
struct sockaddr_in sin;
sin.sin_family =AF_INET;
sin.sin_port =htons(8888);
sin.sin_addr.s_addr =inet_addr(IP);
//绑定服务器的ip端口和地址,必须绑定
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd, 10)<0)
{
ERR_MSG("listen");
return -1;
}
printf("listen succes\n");
struct sockaddr_in cin;
int a=sizeof(cin);
int newfd;
pid_t pid;
while(1)
{
newfd=accept(sfd, (struct sockaddr*)&cin, &a);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
printf("%d\n", newfd);
pid = fork();
if(0==pid)
{
close(sfd);
rcv_cli_msg(newfd, cin);
close(newfd);
exit(0);
}
else if(pid>0)
{
close(newfd);
}
else
{
ERR_MSG("fork");
return -1;
}
}
close(sfd);
return 0;
}
int rcv_cli_msg(int newfd, struct sockaddr_in cin)
{
char buf[128]="";
ssize_t res=0;
while(1)
{
bzero(buf, sizeof(buf));
//接受
res=recv(newfd, buf, sizeof(buf), 0);
if(res<0)
{
ERR_MSG("recv");
return -1;
}
else if(0==res)
{
fprintf(stderr, "newfd=%d客户端关闭\n", newfd);
break;
}
printf("newfd=%d : %s\n", newfd, buf);
//发送
strcat(buf, "*_*");
if(send(newfd,buf, sizeof(buf),0)<0 )
{
ERR_MSG("send");
return -1;
}
printf("发送成功\n");
}
return 0;
}
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#define IP "192.168.31.197"
#define ERR_MSG(msg) do{\
fprintf(stderr, "__%d__", __LINE__);\
perror(msg);\
}while(0)
void* callback(void* arg);
struct msg
{
int newfd;
struct sockaddr_in sed;
};
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;
}
printf("允许端口快速重用设置成功\n");
//填充ip和端口到地址信息集团构体中
struct sockaddr_in sin;
sin.sin_family =AF_INET;
sin.sin_port =htons(8888);
sin.sin_addr.s_addr =inet_addr(IP);
//绑定服务器的ip端口和地址,必须绑定
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd, 10)<0)
{
ERR_MSG("listen");
return -1;
}
printf("listen succes\n");
struct sockaddr_in sed;
int a=sizeof(sed);
pthread_t tid;
struct msg info;
while(1)
{
int newfd=accept(sfd, (struct sockaddr*)&sed, &a);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
printf("newfd=%d\n", newfd);
info.newfd=newfd;
info.sed=sed;
pthread_create(&tid, NULL, callback, (void*)&info);
pthread_detach(tid);
}
close(sfd);
return 0;
}
void* callback(void* arg)
{
struct msg info=*(struct msg*)arg;
int newfd = info.newfd;
struct sockaddr_in sed=info.sed;
char buf[128]="";
ssize_t res=0;
while(1)
{
bzero(buf, sizeof(buf));
//接受
res=recv(newfd, buf, sizeof(buf), 0);
if(res<0)
{
ERR_MSG("recv");
break;
}
else if(0==res)
{
fprintf(stderr, "newfd=%d客户端关闭\n", newfd);
break;
}
printf("newfd=%d : %s\n", newfd, buf);
//发送
strcat(buf, "*_*");
if(send(newfd,buf, sizeof(buf),0)<0 )
{
ERR_MSG("send");
break;
}
printf("发送成功\n");
}
close(newfd);
pthread_exit(NULL);
return 0;
}
TCP流式域套接字
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/un.h>
#define IP "192.168.31.187"
#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;
}
if(access("./unix", F_OK)==0)
{
if(unlink("./unix")<0)
{
ERR_MSG("unlink");
return -1;
}
}
//填充ip和端口到地址信息集团构体中
struct sockaddr_un sun;
sun.sun_family =AF_UNIX;
strcpy(sun.sun_path, "./unix");
//绑定服务器的ip端口和地址,必须绑定
if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun))<0)
{
ERR_MSG("bind");
return -1;
}
//将套接字设置为被动监听状态
if(listen(sfd, 10)<0)
{
ERR_MSG("listen");
return -1;
}
printf("listen succes\n");
//获取新的文件描述符,该文件描述符用于通信,交互的文件
struct sockaddr_un cun;
int a=sizeof(cun);
int newfd=accept(sfd, (struct sockaddr*)&cun, &a);
if(newfd<0)
{
ERR_MSG("accept");
return -1;
}
printf("%d\n", newfd);
char buf[128]="";
ssize_t res=0;
while(1)
{
bzero(buf, sizeof(buf));
//接受
res=recv(newfd, buf, sizeof(buf), 0);
if(res<0)
{
ERR_MSG("recv");
return -1;
}
else if(0==res)
{
fprintf(stderr, "newfd=%d客户端关闭\n", newfd);
break;
}
printf("newfd=%d : %s\n", newfd, buf);
//发送
strcat(buf, "*_*");
if(send(newfd,buf, sizeof(buf),0)<0 )
{
ERR_MSG("send");
return -1;
}
printf("发送成功\n");
}
close(newfd);
close(sfd);
return 0;
}
TCP流式域套接字客户端
#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <sys/un.h>
#define IP "192.168.31.187"
#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");
if(connect(sfd, (struct sockaddr*)&sun, sizeof(sun))<0)
{
ERR_MSG("connect");
return -1;
}
printf("connect success");
char buf[128]="";
ssize_t res;
while(1)
{
bzero(buf, sizeof(buf));
printf("请输入》》");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1]=0;
//发送
if(send(sfd, buf, sizeof(buf), 0)<0)
{
ERR_MSG("send");
return -1;
}
printf("send success\n");
//接收
bzero(buf, sizeof(buf));
res=recv(sfd, buf, sizeof(buf), 0);
if(res<0)
{
ERR_MSG("recv");
return -1;
}
else if(0==res)
{
printf("服务器关闭\n");
break;
}
printf(":%s\n", buf);
}
close(sfd);
return 0;
}
UDP报式域套接字服务器
#include <stdio.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>
#define ERR_MSG(msg) do{\
printf("__%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("./unix1", F_OK)==0)
{
if(unlink("./unix1")<0)
{
ERR_MSG("unlink");
return -1;
}
}
//填充
struct sockaddr_un sun;
sun.sun_family =AF_UNIX;
strcpy(sun.sun_path, "./unix1");
//绑定服务器
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:\n", buf);
printf("%s\n", cun.sun_path);
//发型数据包——》接到谁的数据包就还给谁
strcat(buf, "*_*");
if(sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cun, sizeof(cun))<0)
{
ERR_MSG("send");
return -1;
}
printf("send success\n");
}
close(sfd);
return 0;
}
UDP报域套接字服务器
客户端
#include <stdio.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <sys/un.h>
#define ERR_MSG(msg) do{\
printf("__%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("./unix3", F_OK)==0)
{
if(unlink("./unix3")<0)
{
ERR_MSG("access");
return -1;
}
}
//绑定客户端自身套接字的地址信息结构体
struct sockaddr_un sun;
sun.sun_family =AF_UNIX;
strcpy(sun.sun_path, "./unix3");
if(bind(sfd, (struct sockaddr*)&sun, sizeof(sun))<0)
{
ERR_MSG("bind");
return -1;
}
printf("bind success\n");
printf("%s\n", sun.sun_path);
//填充
struct sockaddr_un sin;
sin.sun_family =AF_UNIX;
strcpy(sin.sun_path, "./unix1");
//绑定服务器
char buf[128]="";
ssize_t res=0;
struct sockaddr_un cin;
socklen_t size=sizeof(cin);
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*)&sin, sizeof(sin))<0)
{
ERR_MSG("send");
return -1;
}
printf("send success\n");
//接收数据包
bzero(buf, sizeof(buf));
res=recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &size);
if(res<0)
{
ERR_MSG("recvfrom");
return -1;
}
printf("%s:\n", buf);
//发型数据包——》接到谁的数据包就还给谁
}
close(sfd);
return 0;
}