免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: zhoulifa
打印 上一主题 下一主题

Linux网络编程一步一步学-IPv6下网络编程步骤 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-02-03 22:51 |只看该作者
是啊,支持

论坛徽章:
0
12 [报告]
发表于 2007-02-03 23:51 |只看该作者
现在有代码都实现IPV4和IPV6通用了,支持精神!

论坛徽章:
0
13 [报告]
发表于 2007-02-04 12:23 |只看该作者
原帖由 converse 于 2007-2-3 22:32 发表
>>还请告诉我如何将此全部发到这里。
汗,你就把帖子一个一个的贴在这个帖子里面就好了,我敢打赌会N热门的~~


那我就当一回搬运工了。不过我觉得这种方式比较那个,好象与咱们信息化时代不太相符哦

论坛徽章:
0
14 [报告]
发表于 2007-02-04 12:29 |只看该作者
原帖由 zhoulifa 于 2007-2-4 12:23 发表


那我就当一回搬运工了。不过我觉得这种方式比较那个,好象与咱们信息化时代不太相符哦


或者在某个帖子里面一次过把所有帖子的链接都放进来,我说的方案都是为了方便别人查看你的帖子罢了。

论坛徽章:
0
15 [报告]
发表于 2007-02-04 12:30 |只看该作者

Linux网络编程一步一步学-简单客户端编写


  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <sys/socket.h>
  5. #include <resolv.h>
  6. #include <stdlib.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h>

  10. #define MAXBUF 1024
  11. /************关于本文档********************************************
  12. *filename: simple-socket.c
  13. *purpose: 演示最基本的网络编程步骤,这是个客户端程序
  14. *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
  15. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
  16. *date time:2007-01-23 19:41:54
  17. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
  18. * 但请遵循GPL
  19. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
  20. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
  21. *********************************************************************/
  22. int main(int argc, char **argv)
  23. {
  24.     int sockfd;
  25.     struct sockaddr_in dest;
  26.     char buffer[MAXBUF];

  27.     if (argc != 3) {
  28.         printf
  29.             ("参数格式错误!正确用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
  30.              argv[0], argv[0]);
  31.         exit(0);
  32.     }
  33.     /* 创建一个 socket 用于 tcp 通信 */
  34.     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  35.         perror("Socket");
  36.         exit(errno);
  37.     }

  38.     /* 初始化服务器端(对方)的地址和端口信息 */
  39.     bzero(&dest, sizeof(dest));
  40.     dest.sin_family = AF_INET;
  41.     dest.sin_port = htons(atoi(argv[2]));
  42.     if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
  43.         perror(argv[1]);
  44.         exit(errno);
  45.     }

  46.     /* 连接服务器 */
  47.     if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
  48.         perror("Connect ");
  49.         exit(errno);
  50.     }

  51.     /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
  52.     bzero(buffer, MAXBUF);
  53.     recv(sockfd, buffer, sizeof(buffer), 0);
  54.     printf("%s", buffer);

  55.     /* 关闭连接 */
  56.     close(sockfd);
  57.     return 0;
  58. }
复制代码

编译此程序使用如下命令:
gcc -Wall simple-socket.c

运行此程序使用如下命令(假设你的主机上开启了ssh服务):
./a.out 127.0.0.1 22


其实socket客户端编程相当简单:
第1步:建立一个socket句柄,用socket()函数;
第2步:设定你要连接的服务器的IP地址和端口等信息;
第3步:与服务器建立连接,用connect函数;
第4步:收发消息,用recv(sockfd,...)/send(sockfd,...)或者read(sockfd,...)/write(sockfd,...)都可以;
第5步:通讯结束后关闭连接,用close()函数即可,当然也有人用shutdown()函数。


[ 本帖最后由 zhoulifa 于 2007-2-4 12:48 编辑 ]

论坛徽章:
0
16 [报告]
发表于 2007-02-04 12:50 |只看该作者

Linux网络编程一步一步学-绑定IP和端口

为了服务器的安全,有些服务器要求客户端只能以指定的IP地址和特定的端口才能连接上来。这就要求我们客户端连接之前绑定IP地址和端口信息。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <sys/socket.h>
  5. #include <resolv.h>
  6. #include <stdlib.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h>

  10. #define MAXBUF 1024
  11. /************关于本文档********************************************
  12. *filename: simple-bind.c
  13. *purpose: 演示最基本的网络编程步骤,这是个客户端程序以固定 IP 和端口连接服务器
  14. *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
  15. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
  16. *date time:2007-01-23 19:51:54
  17. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
  18. * 但请遵循GPL
  19. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
  20. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
  21. *********************************************************************/
  22. int main(int argc, char **argv)
  23. {
  24.     int sockfd;
  25.     struct sockaddr_in dest, mine;
  26.     char buffer[MAXBUF];

  27.     if (argc != 5) {
  28.         printf
  29.             ("参数格式错误!正确用法如下:\n\t\t%s 对方IP地址 对方端口 本机IP地址 本机端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来以本机固定的端口从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
  30.              argv[0], argv[0]);
  31.         exit(0);
  32.     }
  33.     /* 创建一个 socket 用于 tcp 通信 */
  34.     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  35.         perror("Socket");
  36.         exit(errno);
  37.     }

  38.     /* 初始化服务器端(对方)的地址和端口信息 */
  39.     bzero(&dest, sizeof(dest));
  40.     dest.sin_family = AF_INET;
  41.     dest.sin_port = htons(atoi(argv[2]));
  42.     if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
  43.         perror(argv[1]);
  44.         exit(errno);
  45.     }

  46.     /* 初始化自己的地址和端口信息 */
  47.     bzero(&mine, sizeof(mine));
  48.     mine.sin_family = AF_INET;
  49.     mine.sin_port = htons(atoi(argv[4]));
  50.     if (inet_aton(argv[3], (struct in_addr *) &mine.sin_addr.s_addr) == 0) {
  51.         perror(argv[3]);
  52.         exit(errno);
  53.     }

  54.     /* 把自己的 IP 地址信息和端口与 socket 绑定 */
  55.     if (bind(sockfd, (struct sockaddr *) &mine, sizeof(struct sockaddr)) ==
  56.         -1) {
  57.         perror(argv[3]);
  58.         exit(errno);
  59.     }

  60.     /* 以自己特定的端口和IP连接服务器的特定端口 */
  61.     if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
  62.         perror("Connect ");
  63.         exit(errno);
  64.     }

  65.     /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
  66.     bzero(buffer, MAXBUF);
  67.     recv(sockfd, buffer, sizeof(buffer), 0);
  68.     printf("%s", buffer);
  69.     sleep(10);
  70.     /* 关闭连接 */
  71.     close(sockfd);
  72.     return 0;
  73. }
复制代码

编译程序用此命令:
gcc -Wall simple-bind.c

运行程序用此命令:
./a.out 127.0.0.1 22 127.0.0.1 3000

同时可以用下列netstat命令查看网络连接状态:
netstat -an|grep 3000

查看到如下信息:
tcp 0 0 127.0.0.1:3000 127.0.0.1:22 ESTABLISHED


与前面一份源代码相比,这里多了设置自己的IP地址和端口信息,所以编程过程变成了:
第1步:建立一个socket句柄,用socket()函数;
第2步:设定你要连接的服务器的IP地址和端口等信息;
第x步:设定你自己的IP地址和端口等信息与socket绑定,用bind()函数; #与前面相比就是多了这一个步骤
第3步:与服务器建立连接,用connect函数;
第4步:收发消息,用recv(sockfd,...)/send(sockfd,...)或者read(sockfd,...)/write(sockfd,...)都可以;
第5步:通讯结束后关闭连接,用close()函数即可,当然也有人用shutdown()函数。

[ 本帖最后由 zhoulifa 于 2007-2-4 12:55 编辑 ]

论坛徽章:
0
17 [报告]
发表于 2007-02-04 12:57 |只看该作者

Linux网络编程一步一步学-循环读取服务器上的数据


  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include <sys/socket.h>
  5. #include <resolv.h>
  6. #include <stdlib.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h>

  10. #define MAXBUF 10
  11. /************关于本文档********************************************
  12. *filename: simple-readall.c
  13. *purpose: 演示最基本的网络编程,循环读取服务器上发过来的内容,直到读完为止
  14. *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
  15. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
  16. *date time:2007-01-23 20:16:54
  17. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
  18. * 但请遵循GPL
  19. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
  20. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
  21. *********************************************************************/
  22. int main(int argc, char **argv)
  23. {
  24.     int sockfd, ret;
  25.     struct sockaddr_in dest, mine;
  26.     char buffer[MAXBUF + 1];

  27.     if (argc != 5) {
  28.         printf
  29.             ("参数格式错误!正确用法如下:\n\t\t%s 对方IP地址 对方端口 本机IP地址 本机端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来以本机固定的端口从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
  30.              argv[0], argv[0]);
  31.         exit(0);
  32.     }
  33.     /* 创建一个 socket 用于 tcp 通信 */
  34.     if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  35.         perror("Socket");
  36.         exit(errno);
  37.     }

  38.     /* 初始化服务器端(对方)的地址和端口信息 */
  39.     bzero(&dest, sizeof(dest));
  40.     dest.sin_family = AF_INET;
  41.     dest.sin_port = htons(atoi(argv[2]));
  42.     if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
  43.         perror(argv[1]);
  44.         exit(errno);
  45.     }

  46.     /* 初始化自己的地址和端口信息 */
  47.     bzero(&mine, sizeof(mine));
  48.     mine.sin_family = AF_INET;
  49.     mine.sin_port = htons(atoi(argv[4]));
  50.     if (inet_aton(argv[3], (struct in_addr *) &mine.sin_addr.s_addr) == 0) {
  51.         perror(argv[3]);
  52.         exit(errno);
  53.     }

  54.     /* 把自己的 IP 地址信息和端口与 socket 绑定 */
  55.     if (bind(sockfd, (struct sockaddr *) &mine, sizeof(struct sockaddr)) ==
  56.         -1) {
  57.         perror(argv[3]);
  58.         exit(errno);
  59.     }

  60.     /* 连接服务器 */
  61.     if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
  62.         perror("Connect ");
  63.         exit(errno);
  64.     }

  65.     /* 接收对方发过来的消息,每次最多接收 MAXBUF 个字节,直到把对方发过来的所有消息接收完毕为止 */
  66.     do {
  67.         bzero(buffer, MAXBUF + 1);
  68.         ret = recv(sockfd, buffer, MAXBUF, 0);
  69.         printf("读到%d个字节,它们是:'%s'\n", ret, buffer);
  70.     } while (ret == MAXBUF);

  71.     /* 关闭连接 */
  72.     close(sockfd);
  73.     return 0;
  74. }
复制代码

编译程序使用如下命令:
gcc -Wall simple-readall.c

运行程序用如下命令:
./a.out 127.0.0.1 22 127.0.0.1 3000

此程序运行结果如下:
读到10个字节,它们是:'SSH-2.0-Op'
读到10个字节,它们是:'enSSH_4.3p'
读到10个字节,它们是:'2 Debian-5'
读到8个字节,它们是:'ubuntu1
'

注意:如果你运行时程序长久没有退出,请把程序的第一行:
#define MAXBUF 10

稍微改一下,比如改成下面的:
#define MAXBUF 9

再编译运行试试。
为什么?请继续看下一篇文章“设置非阻塞方式”。

论坛徽章:
0
18 [报告]
发表于 2007-02-04 13:00 |只看该作者

Linux网络编程一步一步学-设置非阻塞方式

[code]
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>

#define MAXBUF 10
/************关于本文档********************************************
*filename: simple-nonblock.c
*purpose: 演示最基本的网络编程,循环读取服务器上发过来的内容,直到读完为止
*wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
*date time:2007-01-23 20:46:54
*Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
* 但请遵循GPL
*Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
* 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
*********************************************************************/
int main(int argc, char **argv)
{
    int sockfd, ret, rcvtm = 0;
    struct sockaddr_in dest, mine;
    char buffer[MAXBUF + 1];

    if (argc != 5) {
        printf
            ("参数格式错误!正确用法如下:\n\t\t%s 对方IP地址 对方端口 本机IP地址 本机端口\n\t比如:\t%s 127.0.0.1 80\n此程序用来以本机固定的端口从某个 IP 地址的服务器某个端口接收最多 MAXBUF 个字节的消息",
             argv[0], argv[0]);
        exit(0);
    }

    /* 创建一个 socket 用于 tcp 通信 */
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket");
        exit(errno);
    }

    /* 初始化服务器端(对方)的地址和端口信息 */
    bzero(&dest, sizeof(dest));
    dest.sin_family = AF_INET;
    dest.sin_port = htons(atoi(argv[2]));
    if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {
        perror(argv[1]);
        exit(errno);
    }

    /* 初始化自己的地址和端口信息 */
    bzero(&mine, sizeof(mine));
    mine.sin_family = AF_INET;
    mine.sin_port = htons(atoi(argv[4]));
    if (inet_aton(argv[3], (struct in_addr *) &mine.sin_addr.s_addr) == 0) {
        perror(argv[3]);
        exit(errno);
    }

    /* 把自己的 IP 地址信息和端口与 socket 绑定 */
    if (bind(sockfd, (struct sockaddr *) &mine, sizeof(struct sockaddr)) ==
        -1) {
        perror(argv[3]);
        exit(errno);
    }

    /* 连接服务器 */
    if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {
        perror("Connect ");
        exit(errno);
    }

    /* 设置 socket 属性为非阻塞方式 */
    if (fcntl(sockfd, F_SETFL, O_NONBLOCK) == -1) {
        perror("fcntl");
        exit(errno);
    }

    /* 接收对方发过来的消息,每次最多接收 MAXBUF 个字节,直到把对方发过来的所有消息接收完毕为止 */
    do {
      _retry:
        bzero(buffer, MAXBUF + 1);
        ret = recv(sockfd, buffer, MAXBUF, 0);
        if (ret > 0)
            printf("读到%d个字节,它们是:'%s'\n", ret, buffer);

        if (ret < 0) {
            if (errno == EAGAIN) {
                if (rcvtm)
                    break;
                else {
                    printf("数据还未到达!\n");
                    usleep(100000);
                    goto _retry;
                };
            };
            printf("接收出错了!\n");
            perror("recv");
        }
        rcvtm++;
    } while (ret == MAXBUF);

    /* 关闭连接 */
    close(sockfd);
    return 0;
}
[code]
编译程序用下列命令:
gcc -Wall simple-nonblock.c

运行程序用下列命令:
./a.out 127.0.0.1 21 127.0.0.1 3000

程序运行输出结果如下:
数据还未到达!
读到10个字节,它们是:'220 (vsFTP'
读到10个字节,它们是:'d 2.0.4)
'


问题:

1、非阻塞是什么?
网络通信有阻塞和非阻塞之分,例如对于接收数据的函数recv:在阻塞方式下,没有数据到达时,即接收不到数据时,程序会停在recv函数这里等待数据的到来;而在非阻塞方式下就不会等,如果没有数据可接收就立即返回-1表示接收失败。
2、什么是errno?
errno是Linux系统下保存当前状态的一个公共变量,当前程序运行时进行系统调用如果出错,则会设置errno为某个值以告诉用户出了什么错误。可以用printf("%d %s\n", errno, strerror(errno));得到具体信息。
3、什么是EAGAIN?
man recv
当recv系统调用返回这个值时表示recv读数据时,对方没有发送数据过来。

论坛徽章:
0
19 [报告]
发表于 2007-02-04 13:11 |只看该作者

Linux网络编程一步一步学-开启网络监听服务


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <sys/wait.h>
  9. #include <unistd.h>
  10. #include <arpa/inet.h>

  11. /************关于本文档********************************************
  12. *filename: simple-listen.c
  13. *purpose: 演示最基本的网络编程步骤,开启服务端的监听,等待客户端来连接
  14. *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
  15. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
  16. *date time:2007-01-24 12:31:00
  17. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
  18. * 但请遵循GPL
  19. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
  20. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
  21. *********************************************************************/

  22. int main(int argc, char **argv)
  23. {
  24.     int sockfd;
  25.     struct sockaddr_in my_addr;
  26.     unsigned int myport, lisnum;

  27.     if (argv[1])
  28.         myport = atoi(argv[1]);
  29.     else
  30.         myport = 7838;

  31.     if (argv[2])
  32.         lisnum = atoi(argv[2]);
  33.     else
  34.         lisnum = 2;

  35.     if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  36.         perror("socket");
  37.         exit(1);
  38.     } else
  39.         printf("socket created\n");

  40.     bzero(&my_addr, sizeof(my_addr));
  41.     my_addr.sin_family = PF_INET;
  42.     my_addr.sin_port = htons(myport);
  43.     if (argv[3])
  44.         my_addr.sin_addr.s_addr = inet_addr(argv[3]);
  45.     else
  46.         my_addr.sin_addr.s_addr = INADDR_ANY;

  47.     if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
  48.         == -1) {
  49.         perror("bind");
  50.         exit(1);
  51.     } else
  52.         printf("binded\n");

  53.     if (listen(sockfd, lisnum) == -1) {
  54.         perror("listen");
  55.         exit(1);
  56.     } else
  57.         printf("begin listen\n");

  58.     sleep(100);
  59.     close(sockfd);
  60.     return 0;
  61. }
复制代码

编译程序用下列命令:
gcc -Wall simple-listen.c

运行程序用如下命令:
./a.out 7838 2

这将在你自己主机的所有IP地址是等待客户端连接。比如你的网卡lo的IP地址127.0.0.1,又比如你的网卡eth0的IP地址192.168.0.100
如果要指定只在某个地址是开启监听服务,可以用下面的命令:
./a.out 7838 2 127.0.0.1

这样,客户端只能通过127.0.0.1的7838端口连接你的程序。
你可以开启一个终端输入telnet 127.0.0.1 7838来测试是否能连接成功。
同时可以用netstat -an|grep 7838命令来查看网络是否连接正常

其实socket服务器端编程也是相当简单的:
第1步:建立一个socket句柄,用socket()函数;
第2步:设定自己服务器的IP地址和端口等信息,是用于让对方连接的;
第3步:把自己的IP地址和端口等信息与socket绑定,用bind()函数;
第4步:开启监听服务,用listen()函数;    #至此,客户端已经能连接你这个IP地址和端口了
注:但由于我们还没有接受客户端的连接,没有建立用于消息收发的socket句柄,所以客户端还没法一客户端进行消息收发。

论坛徽章:
0
20 [报告]
发表于 2007-02-04 13:19 |只看该作者

Linux网络编程一步一步学-接受客户端连接请求


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8. #include <sys/wait.h>
  9. #include <unistd.h>
  10. #include <arpa/inet.h>

  11. /************关于本文档********************************************
  12. *filename: simple-accept.c
  13. *purpose: 演示最基本的网络编程步骤,开启服务端的监听,并接收每个客户端的连接请求
  14. *wrote by: zhoulifa(zhoulifa@163.com) 周立发(http://zhoulifa.bokee.com)
  15. Linux爱好者 Linux知识传播者 SOHO族 开发者 最擅长C语言
  16. *date time:2007-01-24 12:41
  17. *Note: 任何人可以任意复制代码并运用这些文档,当然包括你的商业用途
  18. * 但请遵循GPL
  19. *Hope:希望越来越多的人贡献自己的力量,为科学技术发展出力
  20. * 科技站在巨人的肩膀上进步更快!感谢有开源前辈的贡献!
  21. *********************************************************************/

  22. int main(int argc, char **argv)
  23. {
  24.     int sockfd, new_fd;
  25.     socklen_t len;
  26.     struct sockaddr_in my_addr, their_addr;
  27.     unsigned int myport, lisnum;

  28.     if (argv[1])
  29.         myport = atoi(argv[1]);
  30.     else
  31.         myport = 7838;

  32.     if (argv[2])
  33.         lisnum = atoi(argv[2]);
  34.     else
  35.         lisnum = 2;

  36.     if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  37.         perror("socket");
  38.         exit(1);
  39.     } else
  40.         printf("socket created\n");

  41.     bzero(&my_addr, sizeof(my_addr));
  42.     my_addr.sin_family = PF_INET;
  43.     my_addr.sin_port = htons(myport);
  44.     if (argv[3])
  45.         my_addr.sin_addr.s_addr = inet_addr(argv[3]);
  46.     else
  47.         my_addr.sin_addr.s_addr = INADDR_ANY;

  48.     if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))
  49.         == -1) {
  50.         perror("bind");
  51.         exit(1);
  52.     } else
  53.         printf("binded\n");

  54.     if (listen(sockfd, lisnum) == -1) {
  55.         perror("listen");
  56.         exit(1);
  57.     } else
  58.         printf("begin listen\n");

  59.     while (1) {
  60.         len = sizeof(struct sockaddr);
  61.         if ((new_fd =
  62.              accept(sockfd, (struct sockaddr *) &their_addr,
  63.                     &len)) == -1) {
  64.             perror("accept");
  65.             exit(errno);
  66.         } else
  67.             printf("server: got connection from %s, port %d, socket %d\n",
  68.                    inet_ntoa(their_addr.sin_addr),
  69.                    ntohs(their_addr.sin_port), new_fd);
  70.     }

  71.     close(sockfd);
  72.     return 0;
  73. }
复制代码

编译程序用下列命令:
gcc -Wall simple-accept.c

运行程序用如下命令:
./a.out 7838 1 127.0.0.1

另外开多几个客户端程序连接上来,
程序输出结果如下:
server: got connection from 127.0.0.1, port 15949, socket 4
server: got connection from 127.0.0.1, port 15950, socket 5
server: got connection from 127.0.0.1, port 15951, socket 6
server: got connection from 127.0.0.1, port 15952, socket 7


与上一篇相比,这里只是增加了accept函数,这个函数会创建一个新的socket句柄,这个句柄才是我们真正可以用来通讯的句柄,即客户端和服务端的消息收发是通过这个accept产生的socket进行的
accpet是一个典型的阻塞函数,即程序会停止在accept函数处直到有客户端连接上来才会返回。

[ 本帖最后由 zhoulifa 于 2007-2-4 13:37 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP