首页 > 系统服务 > 详细

macos下简单的socket服务器+客户端

时间:2019-10-08 11:27:36      阅读:176      评论:0      收藏:0      [点我收藏+]

TCP客户端服务器编程模型:

服务器:

  1. 调用socket函数创建套接字
  2. 调用bind绑定本地IP和端口
  3. 调用listen启动监听(准备好接收客户端链接的队列)
  4. 调用accept从已连接队列中提取第一个连接。(如果没有,会阻塞。)
  5. 调用I/O函数(read/write)与客户端通讯
  6. 调用close关闭套接字。(多个套接字)

客户端:

  1. 调用socket创建套接字
  2. 调用connect连接服务器
  3. 调用I/O函数(read/write)与服务器通讯
  4. 调用close关闭套接字

 

Linux下和Mac下代码一样的,可能有头文件不太一样,用man命令进去查看即可。

功能:

  1. 客户端连到服务器,服务器打印连接的客户端IP和端口,返回给客户端当前服务器时间。
  2. 服务器加了一个信号捕获函数,ctrl+c停止服务器进程。
  3. 如果不写客户端,使用telnet 127.0.0.1 8888 依然可以收到服务器返回的时间字符串。

服务器代码:

#include <sys/socket.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>

#define SERVER_PORT 8888
#define LISTEN_QUEUE_SISE 10

int socketfd;

void signal_handler(int signo)
{
    printf("this serveice close\n");
    close(socketfd);
    exit(1);
}

void out_clientinfo(const struct sockaddr_in* outsockaddr)
{
    char ipstr[16];
    memset(ipstr, 0, sizeof(ipstr));
    // 将地址从网络字节序转换为点分十进制
    inet_ntop(AF_INET, &outsockaddr->sin_addr.s_addr, ipstr, sizeof(ipstr));

    printf("Connected by %s(%d)\n", ipstr, ntohs(outsockaddr->sin_port));
}

void dosomething(int fd)
{
    //获取系统当前时间
    long t = time(0);
    char* times = ctime(&t);
    size_t size = strlen(times)*sizeof(char);
    //将时间写回到客户端
    if(write(fd, times, size) != size)
    {
        perror("write to client error");
    }
}


int main(int argc, char const *argv[])
{
    if (signal(SIGINT, signal_handler))
    {
        perror("signal error");
        exit(1);
    }

    // 1 sokect
    // AF_INET ipv4
    // SOCK_STREAM tcp
    if((socketfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("socket error");
        exit(1);
    }

    // 2 bind 绑定本地地址和端口
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;//ipv4
    serveraddr.sin_port = htons(SERVER_PORT); //端口
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//响应任意网卡的请求
    if(bind(socketfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0)
    {
        perror("bind error");
        exit(1);
    }

    // 3 listen 启动监听 通知系统接受来自客户端的连接 准备好连接队列
    if(listen(socketfd, LISTEN_QUEUE_SISE) < 0)
    {
        perror("listen error");
        exit(1);
    }
    struct sockaddr_in clientaddr;
    socklen_t clientaddr_len = sizeof(clientaddr);
    while(1)
    {    
        // 4 accept 从队列拿出第一个
        // clientaddr获取客户端的地址信息,是传出参数
        int clientfd = accept(socketfd, (struct sockaddr*)&clientaddr, &clientaddr_len);
        if (clientfd  < 0)
        {
            perror("accept error");
            continue;
        }
        // 5 read/write
        out_clientinfo(&clientaddr);
        dosomething(clientfd);

        // 6 close
        close(clientfd);
    }
    
    // 6 close
    return 0;
}

客户端代码:

#include <sys/socket.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>

#define SERVER_PORT 8888
#define SERVER_IP 127.0.0.1

int main(int argc, char const *argv[])
{
    //1 创建socket

    int socketfd = socket(AF_INET, SOCK_STREAM, 0);
    if (socketfd < 0)
    {
        perror("socket error");
        exit(1);
    }

    //2 connect
    struct sockaddr_in serveraddr;
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(SERVER_PORT);

    if(connect(socketfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr)) < 0 )
    {
        perror("connect error");
        exit(1);
    }

    //3 read write
    char buf[1024];
    if (read(socketfd, buf, sizeof(buf)) > 0)
    {
        printf("%s",buf);
    }

    //4 close
    close(socketfd);
    return 0;
}

 

macos下简单的socket服务器+客户端

原文:https://www.cnblogs.com/lan0725/p/11634267.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!