c语言 socket网络编程

引用图片了解客户端、服务器基本架构

连接图

一、socket函数(创建一个新的socket)

1.头文件:

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

2.函数原型:

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

3.参数:

1)通信协议

AF_INET Ipv4 网络协议
AF_INET6 Ipv6 网络协议

2)通信类型

1、SOCK_STREAM 提供双向连续且可信赖的数据流, 即TCP. 支持 OOB 机制, 在所有数据传送前必须使用connect()来建立连线状态.
2、SOCK_DGRAM 使用不连续不可信赖的数据包连接
3、SOCK_SEQPACKET 提供连续可信赖的数据包连接
4、SOCK_RAW 提供原始网络协议存取
5、SOCK_RDM 提供可信赖的数据包连接

3) 一般设为零

4.返回值:成功返回socket套接字的网络标识符,失败则返回-1。

二、bind函数(绑定端口号、IP地址)

1.头文件:#include<sys/socket.h>

2.函数原型:int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

3.参数:

1)网络描述符(既是socket函数创建成功的返回值)

2)第二个参数是一个指向特定协议的地址结构的指针

结构体名: sockaddr_in
头文件:#include<linux/in.h>
结构体成员1:sin_family(通信协议一般IPV4为AF_INET)。
结构体成员2:sin_ port(端口号)(需要用到主机端口号转网络传输方式函数–htons)。
结构体成员3:struct in_addr sin_addr(又是一个结构体)(配置网络IP地址)(需要用到inet_aton函数–网络的阿斯克码转网络传输方式)。

3)第三个参数是地址结构体的长度

4.返回值:成功返回0,失败返回-1,发送错误信息。

三、listen函数(监听)

1.头文件:

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

2.函数原型:int listen(int sockfd, int backlog);

3.参数:

1)网络标识符(既是socket函数的成功调用的返回值)

2)承载量(表示最多可同时监听的数量)

4.返回值:成功返回0,失败返回-1,并且返回错误信息

四、accept函数(等待连接,运行时阻塞至客户端成功接入)

1.头文件:

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

2.函数原型:

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

3.参数:

1)网络标识符(同上)

2)结构体指针(保存连接的网络信息)

3) 结构体的长度

4.返回值:成功返回接入网络的客户端网络标识符,失败返回-1,返回错误信息。

五、connect函数(客户端接入服务器函数)

1.头文件:

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

2.函数原型:

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

3.参数:

1)网络标识符(客户端成功调用socket函数的返回值)

2)结构体指针(保存连接的网络信息)

3) 结构体的长度

4.返回值:成功返回接入0,失败返回-1,返回错误信息。

六、 连接成功后可用read、write函数进行数据的收发,read、write函数使用见文件编程基础

七、服务器、客户端小程序代码展示

服务器代码

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
    int s_fd;
    int c_fd;
    int n_read;
    char readBuf[128];
    char writeBuf[128];
    int n_write;
    struct sockaddr_in s_addr;
    struct sockaddr_in c_addr;
    memset(&s_addr, 0, sizeof(struct sockaddr_in));
    memset(&c_addr, 0, sizeof(struct sockaddr_in));
    // socket
    s_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (s_fd == -1) {
        perror("socket");
        exit(-1);
    }
    // init struct sockaddr_in
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(atoi(argv[1]));
    inet_aton("192.168.81.129", &s_addr.sin_addr);
    // bind
    bind(s_fd, (struct sockaddr *)&s_addr, sizeof(struct sockaddr_in));
    // listen
    listen(s_fd, 10);
    // accept
    // int c_fd = accept(s_fd,(struct sockaddr *)&c_addr,(unsigned
    // *)sizeof(struct sockaddr_in));
    int c_len = sizeof(struct sockaddr_in);
    while (1) {
        c_fd = accept(s_fd, (struct sockaddr *)&c_addr, &c_len);
        // why???
        if (c_fd == -1) {
            perror("accept");
            exit(-1);
        }
        printf("connected to IP: %s\n", inet_ntoa(c_addr.sin_addr));

        if (fork() == 0) {
            if (fork() == 0) {
                while (1) {
                    printf("input: \n");
                    memset(writeBuf, 0, 128);
                    gets(writeBuf);
                    n_write = write(c_fd, writeBuf, strlen(writeBuf));
                    if (n_write == -1) {
                        perror("write");
                    }
                }
            }
            while (1) {
                memset(readBuf, 0, 128);
                n_read = read(c_fd, readBuf, 128);
                if (n_read == -1) {
                    perror("read");
                } else {
                    printf("client message: %s\n", readBuf);
                }
            }
        }
    }
    return 0;
}

客户端代码

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
//#include <linux/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
    int c_fd;
    int n_read;
    char readBuf[128];
    char writeBuf[128];
    struct sockaddr_in c_addr;
    memset(&c_addr, 0, sizeof(struct sockaddr_in));
    // socket
    c_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (c_fd == -1) {
        perror("socket");
        exit(-1);
    }
    // init struct sockaddr_in
    c_addr.sin_family = AF_INET;
    c_addr.sin_port = htons(atoi(argv[1]));
    inet_aton("192.168.81.129", &c_addr.sin_addr);

    int r_con =
        connect(c_fd, (struct sockaddr *)&c_addr, sizeof(struct sockaddr));
    if (r_con == -1) {
        perror("connect");
    }
    while (1) {
        printf("input: \n");
        memset(writeBuf,0,128);
        gets(writeBuf);
        write(c_fd, writeBuf, strlen(writeBuf));

        if (fork() == 0) {
            while (1) {
                memset(readBuf,0,128);
                n_read = read(c_fd, readBuf, 128);
                if (n_read == -1) {
                    perror("read");
                } else {
                    printf("Server Message: %s\n", readBuf);
                }
            }
        }
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值