用进程和线程完成TCP进行通信操作及广播和组播的通信

进程

代码

 #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;
}
相关推荐
安步当歌42 分钟前
【WebRTC】视频发送链路中类的简单分析(下)
网络·音视频·webrtc·视频编解码·video-codec
米饭是菜qy1 小时前
TCP 三次握手意义及为什么是三次握手
服务器·网络·tcp/ip
yaoxin5211231 小时前
第十九章 TCP 客户端 服务器通信 - 数据包模式
服务器·网络·tcp/ip
鹿鸣天涯2 小时前
‌华为交换机在Spine-Leaf架构中的使用场景
运维·服务器·网络
星海幻影2 小时前
网络基础-超文本协议与内外网划分(超长版)
服务器·网络·安全
WeeJot嵌入式2 小时前
网络百问百答(一)
网络
湖南罗泽南2 小时前
p2p网络介绍
网络·网络协议·p2p
有梦想的咕噜2 小时前
Secure Shell(SSH) 是一种网络协议
运维·网络协议·ssh
IPdodo全球网络3 小时前
解析“ChatGPT网络错误”:从网络专线到IP地址的根源与解决方案
网络·tcp/ip·chatgpt
腾科张老师4 小时前
为什么要使用Ansible实现Linux管理自动化?
linux·网络·学习·自动化·ansible