21、网络IPC:套接字(2)

本文介绍了网络编程的基本概念,包括数据传输函数如send、recv及其变种sendto、recvfrom和sendmsg、recvmsg的使用方法。此外,还提供了服务器端和客户端通信程序的实现示例,并解释了如何设置和获取套接字选项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、数据传输

//发送数据,成功返回发送的字节数
//发送成功只能表示数据已经无错误的发送到网络驱动程序上
ssize_t send(int sockfd, const void *buf, size_t nbytes, int flags);

//sendto可以为无连接的套接字指定一个目标地址
//面向连接的套接字连接中隐含目标地址
ssize_t sendto(int sockfd, const void *buf, size_t nbytes, int flags, const struct sockaddr *destaddr, socklen_t destlen);

//指定多重缓冲区传输数据
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
struct msghdr{
    void *msg_name;
    socklen_t msg_namelen;
    struct iovec *msg_iov;
    int msg_iov_len;
    .....
};

//接收数据
ssize_t recv(int sockfd, void *buf, size_t nbytes, int flags);

ssize_t recvfrom(int sockfd, void *restrict buf, size_t len, int flags, struct sockaddr *restrict addr, socklen_t *restrict addrlen);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

2、通信程序-服务器端

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

int main(int argc, char *argv[])
{
    struct sockaddr_in clientaddr, serveraddr;
    int sockfd;
    int connfd;
    int addrlen;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);

    bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
    listen(sockfd,128);
    while(1){
        addrlen = sizeof(clientaddr);
        connfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen); 
        int ret;
        do{
            char buf[1024];
            memset(buf, '\0',sizeof(buf));
            ret = recv(connfd,buf, sizeof(buf), 0);
            write(STDOUT_FILENO, buf, strlen(buf));

            char dst[128];
            printf("from ip:%s\tport:%d\n",inet_ntop(AF_INET, &clientaddr.sin_addr, dst, sizeof(dst)), ntohs(clientaddr.sin_port));
            printf("*------------------------*\n");
            memset(buf, '\0',sizeof(buf));
            read(STDOUT_FILENO, buf, strlen(buf));
            send(connfd,buf,sizeof(buf), 0);
            printf("msg is sent\n");
            printf("*------------------------*\n");
        }while(ret);
        close(connfd);      
    }
    close(sockfd);
    return 0;
}

2、通信程序-客户端

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

int main(int argc, char *argv[])
{
    struct sockaddr_in serveraddr;
    int sockfd;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(atoi(argv[2]));
    inet_pton(AF_INET, argv[1], &serveraddr.sin_addr);

    connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

    while(1){
        char buf[1024] = { 0 };
        read(STDOUT_FILENO, buf, sizeof(buf));
        send(sockfd, buf, strlen(buf), 0);
        printf("msg is sent\n");
        printf("*------------------------*\n");

        memset(buf, '\0',sizeof(buf));
        recv(sockfd,buf, sizeof(buf), 0);
        write(STDOUT_FILENO, buf, strlen(buf));

        char dst[128];
        printf("from ip:%s\tport:%d\n",inet_ntop(AF_INET, &serveraddr.sin_addr, dst, sizeof(dst)), ntohs(serveraddr.sin_port));
        printf("*------------------------*\n");
    }
    close(sockfd);
    return 0;
}

3、

//设置套接字选项
int setsockopt(int sockfd, int level, int option, const void *val, socklen_t len);

//查看选项的当前值
int getsockopt(int socket, int level, int option, void *restrict val, socklen_t *restrict lenp);

4、带外数据:允许更高优先级的数据传输,TCP支持带外数据(称为紧急数据)仅支持一个字节的紧急数据,UDP不支持。TCP支持紧急标记:在普通数据流中紧急数据所在的位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值