进程
代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#define PORT 8888
#define IP "192.168.124.62"
#define ERR_MSG(msg) do{\
fprintf(stderr,"line=%d",__LINE__);\
perror(msg);\
}while(0)
void handler(int sig)
{
while(waitpid(-1,NULL,WNOHANG)>0);
}
int main(int argc, const char *argv[])
{
//创建套接字
int fd = socket(AF_INET,SOCK_STREAM,0);
if(fd<0)
{
ERR_MSG("socket");
return -1;
}
printf("-流式套接字\n");
//捕获17号信息SIGCHLD
if(signal(17,handler) == SIG_ERR)
{
ERR_MSG("signal");
return -1;
}
//允许端口号重复使用
int reuse = 1;
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
printf("端口允许快速重用\n");
//创建一个地址信息结构体,bind绑定需要用到
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
//绑定ip和端口
if(bind(fd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
printf("绑定成功\n");
//将套接字设置为监听状态
if(listen(fd,128)<0)
{
ERR_MSG("listen");
return -1;
}
printf("监听成功\n");
int newfd;
pid_t pid;
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin);
while(1)
{
//获取连接成功的套接字,用于阻塞等待连接
newfd = accept(fd,(struct sockaddr*)&cin,&socklen);
if(newfd <0)
{
ERR_MSG("accept");
return -1;
}
printf("[%s:%d]客户端连接成功%d\n",inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),newfd);
pid = fork();
if(pid == 0)
{
close(fd);
//接收与发送
char buf[128];
ssize_t size;
while(1)
{
//接收
//
bzero(buf,sizeof(buf));//清空数组内容
// size = read(newfd,buf,sizeof(buf));
size = recv(newfd,buf,sizeof(buf),0);
// size = recvfrom(newfd,buf,sizeof(buf),0,NULL,NULL);
if(size<0)
{
ERR_MSG("recv");
return -1;
}else if(size==0)
{
printf("[%s:%d]客户端下线\n",inet_ntoa(sin.sin_addr),ntohs(sin.sin_port));
break;
}
printf("[%s:%d]接收成功newfd=%d:%s\n",inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),newfd,buf);
//发送
printf("服务器回复>>>>");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf)-1] = '\0';
if(send(newfd,buf,sizeof(buf),0)<0)
{
ERR_MSG("send");
break;
}
printf("发送成功\n");
}
close(newfd);
exit(0);
}
close(newfd);
}
close(fd);
return 0;
}
运行结果图:
线程
代码:
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5 #include <arpa/inet.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <stdlib.h>
9 #include <signal.h>
10 #include <sys/wait.h>
11 #include <pthread.h>
12
13 #define PORT 8888
14 #define IP "192.168.124.62"
15 #define ERR_MSG(msg) do{\
16 fprintf(stderr,"line=%d",__LINE__);\
17 perror(msg);\
18 }while(0)
19
20 struct msg
21 {
22 int newfd;
23 struct sockaddr_in cin;
24 };
25 void* huidiaolist(void* arg);
26 int main(int argc, const char *argv[])
27 {
28 //创建套接字
29 int fd = socket(AF_INET,SOCK_STREAM,0);
30 if(fd<0)
31 {
32 ERR_MSG("socket");
33 return -1;
34 }
35 printf("-流式套接字\n");
36 //允许端口号重复使用
37 int reuse = 1;
38 if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
39 {
40 ERR_MSG("setsockopt");
41 return -1;
42 }
43 printf("端口允许快速重用\n");
44 //创建一个地址信息结构体,bind绑定需要用到
45 struct sockaddr_in sin;
46 sin.sin_family = AF_INET;
47 sin.sin_port = htons(PORT);
48 sin.sin_addr.s_addr = inet_addr(IP);
49 //绑定ip和端口
50 if(bind(fd,(struct sockaddr*)&sin,sizeof(sin))<0)
51 {
52 ERR_MSG("bind");
53 return -1;
54 }
55 printf("绑定成功\n");
56
57 //将套接字设置为监听状态
58 if(listen(fd,128)<0)
59 {
60 ERR_MSG("listen");
61 return -1;
62 }
63 printf("监听成功\n");
64
65 int newfd;
66 pid_t pid;
67 struct sockaddr_in cin;
68 socklen_t socklen = sizeof(cin);
69
70 pthread_t tid;
71 struct msg clinfo;
72 while(1)
73 {
74 //获取连接成功的套接字,用于阻塞等待连接
75 newfd = accept(fd,(struct sockaddr*)&cin,&socklen);
76 if(newfd <0)
77 {
78 ERR_MSG("accept");
79 return -1;
80 }
81 printf("[%s:%d]客户端连接成功%d\n",\
82 inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),newfd);
83
84 clinfo.newfd = newfd;
85 clinfo.cin = cin;
86 if(pthread_create(&tid,NULL,huidiaolist,(void*)&clinfo)!=0)
87 {
88 fprintf(stderr,"line=%d",__LINE__);
89 break;
90 }
91 pthread_detach(tid);
92 }
93 close(fd);
94
95 return 0;
96 }
97
98 void* huidiaolist(void* arg)
99 {
100 //接收与发送
101 int newfd = ((struct msg*)arg)->newfd;
102 struct sockaddr_in cin = ((struct msg*)arg)->cin;
103
104 char buf[128];
105 ssize_t size;
106 while(1)
107 {
108 //接收
109 //
110 bzero(buf,sizeof(buf));//清空数组内容
111 // size = read(newfd,buf,sizeof(buf));
112 size = recv(newfd,buf,sizeof(buf),0);
113 // size = recvfrom(newfd,buf,sizeof(buf),0,NULL,NULL);
114 if(size<0)
115 {
116 ERR_MSG("recv");
117 break;
118 }else if(size==0)
119 {
120 printf("[%s:%d]客户端下线\n",\
121 inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
122 break;
123 }
124 printf("[%s:%d]接收成功newfd=%d:%s\n",\
125 inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,buf);
126
127
128 //发送
129 strcpy(buf,"回复");
130 if(send(newfd,buf,sizeof(buf),0)<0)
131 {
132 ERR_MSG("send");
133 break;
134 }
135 printf("发送成功\n");
136 }
137 close(newfd);
138 pthread_exit(NULL);
结果图:
广播
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 6667
#define IP "192.168.124.255"
#define ERR_MSG(msg) do{\
fprintf(stderr,"line:%d\n",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd<0)
{
ERR_MSG("scoket");
return -1;
}
printf("创建流式套接字成功cd=%d\n",fd);
//允许端口被重
int reuse = 1;
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
printf("允许端口被重复使用\n");
//允许广播
if(setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
//绑定服务器地址信息,必须绑定
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr= inet_addr(IP);
//绑定IP及端口号
if(bind(fd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
printf("绑定成功\n");
char arr[128];
struct sockaddr_in cin;
socklen_t addrlen = sizeof(arr);
while(1)
{
//发送数据
printf("请输入数据>>>>>");
fgets(arr,sizeof(arr),stdin);
arr[strlen(arr)-1] = '\0';
if(sendto(fd,arr,sizeof(arr),0,\
(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
bzero(arr,sizeof(arr));
}
close(fd);
return 0;
}
组播
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 6667
#define IP "224.1.2.3"
#define ERR_MSG(msg) do{\
fprintf(stderr,"line:%d\n",__LINE__);\
perror(msg);\
}while(0)
int main(int argc, const char *argv[])
{
int fd = socket(AF_INET,SOCK_DGRAM,0);
if(fd<0)
{
ERR_MSG("scoket");
return -1;
}
printf("创建流式套接字成功cd=%d\n",fd);
//允许端口被重
int reuse = 1;
if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
printf("允许端口被重复使用\n");
//允许广播
if(setsockopt(fd,SOL_SOCKET,SO_BROADCAST,&reuse,sizeof(reuse))<0)
{
ERR_MSG("setsockopt");
return -1;
}
//绑定服务器地址信息,必须绑定
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr= inet_addr(IP);
//绑定IP及端口号
if(bind(fd,(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("bind");
return -1;
}
printf("绑定成功\n");
char arr[128];
struct sockaddr_in cin;
socklen_t addrlen = sizeof(arr);
while(1)
{
//发送数据
printf("请输入数据>>>>>");
fgets(arr,sizeof(arr),stdin);
arr[strlen(arr)-1] = '\0';
if(sendto(fd,arr,sizeof(arr),0,\
(struct sockaddr*)&sin,sizeof(sin))<0)
{
ERR_MSG("sendto");
return -1;
}
printf("发送成功\n");
bzero(arr,sizeof(arr));
}
close(fd);
return 0;
}