socket之面向连接编程(TCP)

面向连接(有连接)编程的网络应用程序的流程固定,只需要创建服务器和客户端两个应用程序,利用网络传输进行通信

面向连接的服务器端的流程如下

1> 创建套接字(socket)
2> 服务的绑定(bind)
3> 服务的侦听(listen)
4> 处理新到连接(accept)
5> 数据收发(recv/send)
6> 关闭套接字(close)

面向连接的客户端的流程

1> 创建客户端套接字(socket)
2> 发起连接(connect)
3> 数据的收发(recv\send)
4> 套接字的关闭(close)

有连接的编程过程图示:

这里写图片描述

以下是一个简单的有连接的程序实现:


//服务器端的代码
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define QUEUE_SIZE 6        
#define SERVER_PORT 7070    //服务器的端口号
#define SERVER_IP  "192.168.3.66"   //服务器的IP地址

int main(int ac, char *av[])
{
    int sockser = socket(AF_INET, SOCK_STREAM, 0);   //得到服务器端的套接字
    if(sockser == -1){  //得到套接字失败
        printf("socket error.\n");
    }

    //设置地址重用(必须要在绑定之前设置)
    int yes = 1;
    if(setsockopt(sockser, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
        perror("setsockopt");

    struct sockaddr_in addrser, addrcli;   //服务器和客户的地址结构体
    addrser.sin_family = AF_INET;   //设置地址的协议家族
    addrser.sin_port = htons(SERVER_PORT);   //设置地址的端口号
    addrser.sin_addr.s_addr = inet_addr(SERVER_IP);   //设置地址的IP地址

    socklen_t socklen = sizeof(struct sockaddr);   //服务器或客户端的地址结构大小
    int res = bind(sockser, (struct sockaddr*)&addrser, socklen);   //将服务器地址和服务器套接字绑定
    if(res == -1){   //绑定失败
        printf("bind error.\n");
    }

    int res1 = listen(sockser, QUEUE_SIZE);  //监听
    if(res1 == -1){
        printf("listen error.\n");
    }

    printf("wait cli connect.......\n");
    int acc = accept(sockser, (struct sockaddr*)&addrcli, &socklen);  //接收客户端的连接
    if(acc == -1){  //连接失败
        printf("accept error.\n");
    }

    char sendbuf[256];
    char recvbuf[256];
    //客户和服务器之间通信
    //TCP协议下客户和服务器的收发消息的顺序没有要求,谁先发都可以,但是UDP协议必须是客户端先给服务器发消息,这样服务器才会知道自己在和谁通信(因为UDP是无连接的协议)
    while(1){
        printf("Ser:>");
        scanf("%s", sendbuf);
        if(strncmp(sendbuf, "quit", 4) == 0){
            break;
        }
        send(acc, sendbuf, strlen(sendbuf) + 1, 0);  //服务器给客户端发消息
        recv(acc, recvbuf, 256, 0);   //服务器接收客户端的消息
        printf("Cli:> %s\n", recvbuf);
    }
    close(sockser);  //通信结束,关闭服务器端的套接字
    return 0;
}


//客户端的代码
#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

#define SERVER_PORT 7070
#define SERVER_IP  "192.168.3.66"

int main(int ac, char *av[])
{
    int sockcli = socket(AF_INET, SOCK_STREAM, 0);   //得到客户端的套接字
    if(sockcli == -1){  //得到套接字失败
        perror("sockcli");
    }

    struct sockaddr_in addrser;   //服务器的地址结构
    addrser.sin_family = AF_INET;   //设置服务器的协议家族
    addrser.sin_port = htons(SERVER_PORT);  //设置服务器的端口
    addrser.sin_addr.s_addr = inet_addr(SERVER_IP);  //设置服务器的IP地址

    socklen_t addrlen = sizeof(struct sockaddr);   //得到服务器的地址的大小
    int res = connect(sockcli, (struct sockaddr*)&addrser, addrlen);   //连接服务器
    if(res == -1){  //连接服务器失败
        perror("connect");  
    }else{          //连接服务器成功
        printf("cli connect ser ok.\n");
    }

    char sendbuf[256];
    char recvbuf[256];
    //服务器和客户端进行通信
    while(1){
        recv(sockcli, recvbuf, 256, 0);   //客户端先接收服务器发来的消息
        printf("ser:> %s\n", recvbuf);
        printf("cli:>");
        scanf("%s", sendbuf);
        if(strncmp(sendbuf, "quit", 4) == 0){
            break;
        }
        send(sockcli, sendbuf, strlen(sendbuf) + 1, 0);   //客户端发送消息
    }
    close(sockcli);  //通信结束,关闭客户端的套接字

    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/github_33736971/article/details/51553623
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

socket之面向连接编程(TCP)

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭