Linux C Socket简单应用

Linux C Socket简单应用

简单的socket应用。
在这里插入图片描述

server代码

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 33333

int main()
{
    int sockfd;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == -1){
        perror("socket create failed!");
        exit(1);
    }

    int opt = 1;
    setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt));


    struct sockaddr_in addr;

    bzero(&addr, sizeof (struct sockaddr_in));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    addr.sin_addr.s_addr = inet_addr("192.168.43.106"); //自己主机IP

    if(bind(sockfd, (struct sockaddr*)(&addr), sizeof (struct sockaddr_in)) < 0){
        perror("bind failed!");
        exit(1);
    }

    if(listen(sockfd, 3) < 0){
        perror("listen failed!");
        exit(1);
    }

    printf("listen successful\n");


    char buffer[1024];
    while (1) {

        memset(buffer, 0, sizeof(buffer));

        struct sockaddr_in c_addr;
        socklen_t c_len = sizeof (struct sockaddr_in);
        int cfd;

        bzero(&c_addr, sizeof (struct sockaddr_in));
        cfd = accept(sockfd, (struct sockaddr*)(&c_addr), &c_len);
        if(cfd == -1){
            perror("accept failed");
            exit(1);
        }
        printf("accept successful\n");
        printf("port = %d, ip = %s\n", ntohs(c_addr.sin_port), inet_ntoa(c_addr.sin_addr));
        

        recv(cfd, buffer, sizeof(buffer), 0);
        printf("re: %s \n", buffer);

        send(cfd, buffer, sizeof(buffer), 0);
    }



    return 0;
}

client端代码

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 33333

int main()
{
    int sockfd;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd == -1){
        perror("socket create failed!");
        exit(1);
    }

    struct sockaddr_in s_addr;
    bzero(&s_addr, sizeof (struct sockaddr_in));
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(PORT);
    s_addr.sin_addr.s_addr = inet_addr("192.168.43.106");

    if(connect(sockfd, (struct sockaddr*)(&s_addr), sizeof (struct sockaddr_in)) < 0){
        perror("connect failed!");
        exit(1);
    }

    char* message = "hello";

    send(sockfd, message, 5, 0);

    char buf[1024];

    recv(sockfd, buf, sizeof(buf), 0);

    printf("%s\n", buf);

    return 0;
}

1. socket函数

	NAME
       socket - create an endpoint for communication

	SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int socket(int domain, int type, int protocol);

socket()函数创建一个socket并且返回一个对应的描述符。
其参数分别为:
Address Family - AF_INET => IPv4
Type - SOCK_STREAM => socket连接使用TCP协议
Protocol - 0 => 使用IP协议

2. setsockopt,setsockopt函数

NAME
       getsockopt, setsockopt - get and set options on sockets

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int getsockopt(int sockfd, int level, int optname,
                      void *optval, socklen_t *optlen);
       int setsockopt(int sockfd, int level, int optname,
                      const void *optval, socklen_t optlen);

该函数用于获取或者设置与某个套接字关联的选 项
参数:
sockfd:将要被设置或者获取选项的套接字。
level:选项所在的协议层。
optname:需要访问的选项名。
optlen:对于getsockopt(),指向返回选项值的缓冲。对于setsockopt(),指向包含新选项值的缓冲。
optlen:对于getsockopt(),作为入口参数时,选项值的最大长度。作为出口参数时,选项值的实际长度。对于setsockopt(),现选项的长度。

level指定控制套接字的层次.可以取三种值:
1)SOL_SOCKET:通用套接字选项。
2)IPPROTO_IP:IP选项。
3)IPPROTO_TCP:TCP选项。

optname指定控制的方式
SO_REUSERADDR  允许重用本地地址和端口 int

3. bind函数

NAME
       bind - bind a name to a socket

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int bind(int sockfd, const struct sockaddr *addr,
                socklen_t addrlen);

bind()函数可以将socket绑定到一个端口上,client可以通过向这个端口发起请求,端口对应的socket便会与client端的socket连接。

4. listen函数

NAME
       listen - listen for connections on a socket

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int listen(int sockfd, int backlog);

listen => 可以将socket处于监听的状态。
其参数为:
sockfd => 设置监听的socket。
backlog => 在当前连接后面允许存在的最大未处理连接数。

5. accept函数

NAME
       accept, accept4 - accept a connection on a socket

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

       #define _GNU_SOURCE             /* See feature_test_macros(7) */
       #include <sys/socket.h>

       int accept4(int sockfd, struct sockaddr *addr,
                   socklen_t *addrlen, int flags)

accept函数的作用就是接收请求。
参数:
sockfd => socket的描述符
addr =>IP地址结构体,该参数是一个传出参数,我们传入一个空的addr进入,将返回客户端的IP地址数据。
addrlen =>IP地址结构体长度。

该函数的返回值是客户端的sockfd,后续对该客户端进行双向通信需要用到该sockfd返回值。

7. connect函数

NAME
       connect - initiate a connection on a socket

SYNOPSIS
       #include <sys/types.h>          /* See NOTES */
       #include <sys/socket.h>

       int connect(int sockfd, const struct sockaddr *addr,
                   socklen_t addrlen);

connect()函数会向服务器发起请求建立一个连接。
其参数为:
sockfd => socket的描述符
addr => sockaddr的结构体,通用的socket地址
addrlen => socket描述符的长度。

8. recv函数

NAME
       recv, recvfrom, recvmsg - receive a message from a socket

SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t recv(int sockfd, void *buf, size_t len, int flags);

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

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

recv函数用于接受数据,参数很简单。
sockfd 套接字
buf 缓冲区
len 缓冲区长度
flags 标志,一般为0

9. send函数

NAME
       send, sendto, sendmsg - send a message on a socket

SYNOPSIS
       #include <sys/types.h>
       #include <sys/socket.h>

       ssize_t send(int sockfd, const void *buf, size_t len, int flags);

       ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);

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

send函数用于发送数据,参数同revc函数。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值