• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
zuoanddie
博客园    首页    新随笔    联系   管理    订阅  订阅

Linux-网络编程(day13)

 一、基于TCP的网络编程(续day12)

二、并发服务器

三、基于UDP的网络编程

 


 

 

  一、基于TCP的网络编程(续day12)

  1、昨天的例子客户端只能向指定的服务器端发送数据,可以利用主函数参数传递命令行参数,从而接收任意服务器地址。同时也可以实现两台机器之间的通信(可以事先使用ping命令查看是否通)

  2、也可以使用while循环在客户端不断接收数据输入,知道特定字符结束输入关闭通讯,如使用fgets,或gets

#if 0

...

#endif

可以进行条件注释

 

基于TCP的服务器:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
int main()
{
int listenfd = socket (AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
    {
        perror ("socket");
        exit (EXIT_FAILURE);
    }
struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons (8888);
    addr.sin_addr.s_addr = INADDR_ANY;
if (bind (listenfd, (struct sockaddr*)&addr, sizeof (addr)) == -1)
    {
        perror ("bind");
        exit (EXIT_FAILURE);
    }
if (listen (listenfd, 1024) == -1)
    {
        perror ("listen");
        exit (EXIT_FAILURE);
    }
struct sockaddr_in addrcli = {};
    socklen_t addrlen = sizeof (addrcli);
int connfd = accept (listenfd, (struct sockaddr*)&addrcli, &addrlen);
if (connfd == -1)
    {
        perror ("accept");
        exit (EXIT_FAILURE);
    }
    printf ("服务器已接受来自%s:%hu客户机的连接请求\n", inet_ntoa (addrcli.sin_addr),ntohs (addrcli.sin_port));
char buf[1024];
    ssize_t rcvd = recv (connfd, buf, sizeof (buf), 0);
if (rcvd == -1)
    {
        perror ("recv");
        exit (EXIT_FAILURE);
    }
if (rcvd == 0)
    {
        printf ("客户机已关闭连接\n");
        exit (EXIT_FAILURE);
    }
    buf[rcvd] = '\0';
    printf ("客户端说:%s\n", buf);
    printf ("服务器说:");
    gets (buf);
    ssize_t sent = send (connfd, buf, strlen (buf) * sizeof (buf[0]), 0);
if (sent == -1)
    {
        perror ("send");
        exit (EXIT_FAILURE);
    }
if (close (listenfd) == -1)
    {
        perror ("close");
        exit (EXIT_FAILURE);
    }
if (close (connfd) == -1)
    {
        perror ("close");
        exit (EXIT_FAILURE);
    }
return 0;
}

 

 基于TCP的客户端:

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
int main()
{
int listenfd = socket (AF_INET, SOCK_STREAM, 0);
if (listenfd == -1)
    {
        perror ("socket");
        exit (EXIT_FAILURE);
    }
struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons (8888);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect (listenfd, (struct sockaddr*)&addr, sizeof (addr)) == -1)
    {
        perror ("connect");
        exit (EXIT_FAILURE);
    }
char buf[1024] = "你好,服务器";
    printf ("客户端说:%s\n", buf);
    ssize_t sent = send (listenfd, buf, strlen (buf) * sizeof (buf[0]), 0);
if (sent == -1)
    {
        perror ("send");
        exit (EXIT_FAILURE);
    }
    ssize_t rcvd = recv (listenfd, buf, sizeof (buf), 0);
if (rcvd == -1)
    {
        perror ("recv");
        exit (EXIT_FAILURE);
    }
    buf[rcvd] = '\0';
    printf ("服务器说:%s\n", buf);
if (close (listenfd) == -1)
    {
        perror ("close");
        exit (EXIT_FAILURE);
    }
return 0;
}

 

 上述服务器只能给一个客户端提供服务,这就需要后面讲到的并发来解决。

可以使用setsockopt(2)来设置socket属性,或者getsockopt(2)来获取socket属性。


 

 

二、并发服务器

 

1、使用线程实现并发服务器

2、多路复用计数实现并发服务器

  select(2)、poll(2)等

3、使用多进程实现并发服务器

  在这里需要分清楚,父进程,子进程的作用,以及fork的时机。

 

posted @ 2019-06-22 22:18  zuoanddie  阅读(196)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3