• linux网络编程1 最简单的socket编程


    下面是socket编程的服务器端

    先看一个图,1

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<unistd.h>   //针对系统调用的封装    fork,pipe 各种i/o原语 read write 等
     5 
     6 #include<sys/socket.h>
     7 #include<netinet/in.h>    //互联网地址族   定义数据结构sockaddr_in
     8 #include<arpa/inet.h>   //提供IP地址转换函数
     9 
    10 #include<ctype.h>    //一批C语言字符分类函数 用    于 测试字符是否属于特定的字符类别  topper()在这里
    11 
    12 #define MAXLINE 80
    13 #define SER_PORT 8000
    14 
    15 int main(void){
    16 
    17     struct sockaddr_in servaddr,cliaddr;
    18     socklen_t cliaddr_len;
    19 
    20     int listenfd,connfd;
    21     char buf[MAXLINE];
    22     char str[INET_ADDRSTRLEN];
    23     int i,n;
    24     char tt[] = "exit1";   //这里有字符数组和字符指针的区别的坑 具体百度查询
    25     char *bb;
    26 
    27     listenfd = socket(AF_INET,SOCK_STREAM,0);  //   
    28                                                 //  domain 协议域    AF_INET AF_INET6,AF_LOCAL(AF_UNIX) AF_ROUTE   
    29                                                 //  type socket类型   SOCK_STREAM(流式socket 针对tcp )  SOCK_DGRAM(数据包  针对udp) SOCK_RAW 
    30                                                 // protocol  协议  tcp协议,udp协议  stcp协议 tipc协议
    31 
    32     bzero(&servaddr,sizeof(servaddr));   //初始化赋值为0
    33 
    34     servaddr.sin_family = AF_INET;
    35     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);   //任何ip   //这里是大小端的 转换问题。。可以 百度
    36     servaddr.sin_port = htons(SER_PORT);     //端口
    37 
    38     bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr));   //绑定链接的套接字描述符  和  地址和端口
    39 
    40     listen(listenfd,20);
    41 
    42     printf("Accepting connections ... 
     ");
    43     while(1){
    44 
    45         cliaddr_len = sizeof(cliaddr);
    46         connfd = accept(listenfd,(struct sockaddr *)&cliaddr,&cliaddr_len);  //连接的套接字描述符    返回链接的地址   返回地址的缓冲区长度
    47             
    48                                                                             //返回  客户端的套接字描述符
    49         printf("connfd:%d------
    ",connfd);
    50 
    51         printf("received from %s at PORT %d 
    ",
    52                 inet_ntop(AF_INET,&cliaddr.sin_addr,str,sizeof(str)),
    53                 ntohs(cliaddr.sin_port));
    54         while(1){
    55             n = read(connfd,buf,MAXLINE);    //  read(int fd,void *buf, size_t count);    成功返回  读取的字节数   数据保存在buf上   读取客户端的数据
    56 
    57             printf("%d,")
    58             //printf("buf:%s-----%d
    ",buf,strcmp(buf,"exit1"));
    59             //printf("tt:%s-----%d
    ",tt,strcmp(tt,"exit1"));
    60             for(int i=0;i<5;i++){
    61                 tt[i] = buf[i];
    62             }
    63             printf("tt:%s-----%d
    ",tt,strcmp(tt,"exit1"));
    64             if(strcmp(tt,"exit1") == 0){      //strcmp  对比的就是字符
    65                 close(connfd);
    66                 printf("close:-----
    ");
    67                 break;
    68             }
    69 
    70             for(i=0; i < n; i++){
    71                 buf[i] = toupper(buf[i]);
    72             }
    73             write(connfd,buf,n);   //   // 向客户端写入数据   
    74         }                                                                           
    75         
    76     }
    77 
    78     return 0;                       
    79 
    80 }
    81 
    82 //这个程序有漏洞,如果客户端断线或者关闭,服务器就会死循环。   客户端的标准输入是阻塞的。。。其他都不是阻塞的。

    客户端

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<unistd.h>
     5 
     6 #include<sys/socket.h>
     7 #include<netinet/in.h>
     8 #include<arpa/inet.h>
     9 
    10 #include<errno.h>  //错误
    11 
    12 #define MAXLINE 80
    13 #define SER_PORT 8000
    14 
    15 int main(int argc,char *argv[]){
    16 
    17 
    18     struct sockaddr_in servaddr;
    19     char buf[MAXLINE];
    20 
    21     int sockfd,n;
    22     char *str;
    23     char tt[5];
    24 
    25     //if(argc != 2){
    26        // fputs("usage: ./client message 
     ",stderr);
    27        // exit(1);
    28     //}
    29 
    30     //str = argv[1];
    31 
    32     sockfd = socket(AF_INET,SOCK_STREAM,0);
    33 
    34     bzero(&servaddr,sizeof(servaddr));
    35     servaddr.sin_family = AF_INET;
    36     inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);
    37     servaddr.sin_port = htons(SER_PORT);
    38 
    39     if(connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0){
    40             printf("connet error:%s
    ",strerror(errno));
    41         }   //链接服务器
    42 
    43     while(1){
    44         
    45         memset(buf,0,MAXLINE);
    46         printf("client connet server ...
    ");
    47         n = read(STDIN_FILENO,buf,MAXLINE);   //从标准输入  读取数据
    48         for(int i=0;i<5;i++){
    49                 tt[i] = buf[i];
    50             }
    51         if(strcmp(tt,"exit1") == 0){
    52             printf("exit server connect 
    ");
    53             close(sockfd);
    54             return 0;
    55         }
    56 
    57         write(sockfd,buf,n);   //把我们的输入,写到服务器
    58 
    59         if(strcmp(tt,"exit1") == 0){
    60             printf("exit server connect 
    ");
    61             close(sockfd);
    62             return 0;
    63         }
    64 
    65         n = read(sockfd,buf,MAXLINE);    //从服务器读取数据
    66 
    67 
    68         printf("Response from server:
    ");
    69         write(STDOUT_FILENO,buf,n);   //写到标注输出上
    70         printf("
    ");
    71     }
    72     
    73     close(sockfd);
    74     return 0;
    75 
    76 }

    实验结果:

    总结:一个socket建立一个连接,必须配合一个connect,对应的服务器端对应一个accept 。不能多次connet,多次是之后会报错,也不能同一个客户端socket多次accept,因为服务器已经有了,accept会阻塞等待其他客户端的socket。

  • 相关阅读:
    1023. 组个最小数
    1021. 个位数统计
    *1020. 月饼
    *1019. 数字黑洞
    1016. 部分A+B
    *1014. 福尔摩斯的约会
    *1013. 数素数
    *1012. 数字分类
    1011. A+B和C
    *1008. 数组元素循环右移问题
  • 原文地址:https://www.cnblogs.com/etata/p/6524822.html
Copyright © 2020-2023  润新知