Linux网络编程之TCP协议(一版)

ser.c:

#include
#include
#include
#include
#include
#include


int main()
{
    int sockSer = socket(AF_INET, SOCK_STREAM, 0);// 创建套接字
    if(sockSer == -1)// 出错处理
    {
        perror("socket.");
        exit(1);
    }
    struct sockaddr_in addrSer ,addrCli;// 服务端和客户端的套接字地址结构体
    addrSer.sin_family = AF_INET;// 设置服务器端使用Ipv4
    addrSer.sin_port = htons(8080);// 设置服务器端端口为8080
    addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");// 设置服务器端的Ip地址为本地环回地址
    socklen_t addrlen = sizeof(struct sockaddr); // 套接字地址结构体的大小
    int ret = bind(sockSer,(struct sockaddr*)&addrSer,addrlen);// 绑定套接字
    if(ret == -1) 
    {
        close(sockSer);
        perror("bind.");
        exit(1);
    }
    int ret_l = listen(sockSer, 5);// 设置监听,最大连接数为5
    if(ret_l == -1) 
    {
        close(sockSer);
        perror("listen.");
        exit(1);
    }
    int sockConn = accept(sockSer,(struct sockaddr*)&addrCli, &addrlen);// 服务器等待连接
    if(sockConn == -1)
    {
        printf("Server Accept Client Connect Fail.\n");
    }
    else
        printf("Server Accept Client Connect Success.\n");
    char sendbuf[256];
    char recvbuf[256];
    while(1)
    {
        // 客户端和服务器通信的方式是一问一答的方式。应注意避免发生阻塞
        printf("Ser:>");
        scanf("%s",sendbuf);
        send(sockConn, sendbuf, strlen(sendbuf)+1,0);// 通过sockConn套接字来发送、接收数据
        recv(sockConn, recvbuf, 256, 0);
        printf("Cli:>%s\n",recvbuf);
        
    }
    close(sockSer);// 关闭sockSer套接字

}

 ser.c里面用到的Linux接口函数(API)

socket()--创建套接字,parameter1:使用的协议;parameter2:通信的类型;parameter3:一般为0,用于选择parameter2中的特定类型
htons()--将无符号的短整数(端口号)从本地字节序换为网络字节序
inet_addr()--将网络主机地址从Ipv4的点分十进制转换为网络字节序的二进制数据。若输入无效返回-1,但-1是有效地址(255.255.255.255)建议使用inet_aton()输入有效返回非零值,输入无效返回0
bind()--将一个名字和一个套接字绑定到一起,为套接字分配一个本地地址
listen()--在一个套接字上监听连接,并指定监听队列的数目
accept()--在一个套接字上接收连接,第一个参数为socket()创建,并设置过listen()监听的套接字。第二个参数为连接实体填充的套接字地址结构,第三个参数为第二个参数结构体的大小。套接字为阻塞的话,acceppt()将一直等待,直到有连接到达;套接字为非阻塞的话,返回EAGIN
send()--从套接字发送信息,当要发送的消息长度大于套接字当前可用缓冲区时,send 将阻塞,除非在套接字上设置了非阻塞式输入输出模式.对于非阻塞模式,这种情况下将返回 EAGAIN 错误
recv()--从connect套接字接收信息。

cli.c:

#include
#include
#include
#include
#include
#include


int main()
{
    int sockCli = socket(AF_INET, SOCK_STREAM, 0);// 客户端这边也需要创建套接字?
    if(sockCli == -1)
    {
        perror("socket.");
        exit(1);
    }
    // 服务器端的套接字地址结构体
    struct sockaddr_in addrSer;
    addrSer.sin_family =AF_INET;
    addrSer.sin_port = htons(8080);
    addrSer.sin_addr.s_addr = inet_addr("127.0.0.1");
    socklen_t addrlen = sizeof(struct sockaddr);
    int ret = connect(sockCli,(struct sockaddr*)&addrSer, addrlen);
    if(ret == -1)
    {
        printf("Client connect server fail.");
        close(sockCli);
        exit(1);
    }
    else
    {
        printf("Client connect server success.");
    }
    char sendbuf[256];
    char recvbuf[256];
    while(1)
    {
        recv(sockCli,recvbuf,256,0);//客户端收发都是通过sockCli套接字
        printf("Ser:>%s\n",recvbuf);
        printf("Cli:>");
        scanf("%s",sendbuf);
        send(sockCli, sendbuf, strlen(sendbuf)+1,0);
    }
    close(sockCli);
    return 0;
}

 cli.c里面用到的Linux接口函数(API)

connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)
系统调用将文件描述符sockfd引用的套接字连接到addr指定的地址。addrlen参数指定addr的大小。addr中地址的格式由套接字sockfd的地址空间确定。通常,基于连接的协议套接字只能成功一次connect();无连接协议套接字可以多次使用connect()来更改其关联。无连接套接字可以通过连接到地址并将sockaddr的sa_family成员设置为AF_UNSPEC(从内核2.2开始受Linux支持)来解除关联。

 

你可能感兴趣的:(Linux)