linux环境下网络编程

参考

https://www.cnblogs.com/diligenceday/p/6241021.html

https://blog.csdn.net/baidu_36649389/article/details/79081770

http://www.cnblogs.com/wangcq/p/3520400.html

 

socket是网络进程的PID,由运行进程的计算机的IP地址和进程使用的端口组成。

异步状态下connect不阻塞,直接返回-1,connect返回-1是对的
然后通过select进行判断是否连接上
同步状态下connect阻塞,系统莫认时间75秒后,返回成功或失败

TCP编程的流程

服务器端

//
//  main.cpp
//  Server
//
//  Created by 蓝猫 on 2018/12/13.
//  Copyright © 2018年 蓝猫. All rights reserved.
//

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define PORT 25555
#define BACK_LOG 20  //队列允许请求数
#define BUF_SIZE 256 //  缓冲区大小
#define IP "192.168.1.5"
using std::cout;
using std::endl;

int main(int argc, const char * argv[])
{
    int ret;
    time_t tt;
    struct tm *ttm;
    char buf[BUF_SIZE];
    pid_t pid;//定义进程描述符
    int sockfd; //
    int clientfd;
    struct sockaddr_in host_addr;
    struct sockaddr_in client_addr;
    int length=sizeof(clientfd);
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd==-1)
    {
        cout<<"创建socket失败"<<endl;
        exit(1);
    }
    bzero(&host_addr, sizeof(host_addr));
    host_addr.sin_family=AF_INET;//TCP/IP协议
    host_addr.sin_port=htons(PORT);//设置端口
    host_addr.sin_addr.s_addr=INADDR_ANY;//本地ip
    ret=bind(sockfd, (const struct sockaddr *)&host_addr, sizeof(host_addr));//绑定ip和端口
    if(ret==-1)
    {
        cout<<"bind失败"<<endl;
        exit(1);
    }
    else
    {
        cout<<"bind成功"<<endl;
    }
    //监听网络端口
    ret=listen(sockfd, BACK_LOG);
    if(ret==-1)
    {
        cout<<"监听失败"<<endl;
        exit(1);
    }
    while (1)
    {
        /*
          倾听队列之后 accept可以从倾听套接字的完成队列里面接受一个连接,如果队列是空,进程进入睡眠状态。
         accept调用成功
         函数返回值是一个新的标识符,标识接收的连接
         第二个参数描述客户机地址 第三个描述客户机地址长度
         */
        //clientfd=accept(sockfd, (struct sockaddr *)&client_addr, &length);//接收连接请求
        //clientfd=accept(sockfd, (struct sockaddr *)&client_addr,&length);
        clientfd = accept(sockfd, (struct sockaddr*)&client_addr, (socklen_t *)&length);
        if(clientfd==-1)
        {
            cout<<"接收失败"<<endl;
            exit(1);
        }
        pid=fork();
        if(pid==0)
        {
            while (1)
            {
                bzero(buf, sizeof(buf));
                tt=time(NULL);
                ttm=localtime(&tt);//获取当前时间参数
                strcpy(buf, asctime(ttm));// 将时间拷贝到缓冲区
                send(clientfd, buf, strlen(buf), 0);//发送数据
                sleep(2);
            }
            close(clientfd);
        }
        else if(pid>0)
        {
            close(clientfd);//父进程关闭套接字 ,准备下一个客户端连接
        }
    }
    return 0;
}

客户端

//
//  main.cpp
//  Client
//
//  Created by 蓝猫 on 2018/12/13.
//  Copyright © 2018年 蓝猫. All rights reserved.
//
#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#define PORT 25555
#define BACK_LOG 20  //队列允许请求数
#define BUF_SIZE 256 //  缓冲区大小
#define IP "192.168.1.5"
using std::cout;
using std::endl;
int main(int argc, const char * argv[])
{
    int ret;
    char buf[BUF_SIZE];
    int sockfd;//套接字描述符
    struct sockaddr_in serv_addr;// 服务器端的端口号和ip
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd==-1)
    {
        cout<<" socket创建失败"<<endl;
        return 2;
    }
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(PORT);
    inet_aton(IP, (struct in_addr *)&serv_addr.sin_addr.s_addr);
    //serv_addr.sin_addr.s_addr=INADDR_ANY;
    cout<<"here1"<<endl;
    ret=connect(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
    cout<<"here2"<<endl;
    if(ret==-1)
    {
        cout<<"connect失败"<<endl;
        return 3;
    }
    else
    {
        cout<<"connect success"<<endl;
    }
    while (1)
    {
        bzero(buf, sizeof(buf));
        recv(sockfd, buf, sizeof(buf), 0);
        printf("接收到数据:%s",buf);
        sleep(1);
    }
    close(sockfd);
    return 0;
}

用多线程实现客户端和服务器端同时运行

//
//  main.cpp
//  多线程实现tcp c/s交互
//
//  Created by 蓝猫 on 2018/12/14.
//  Copyright © 2018年 蓝猫. All rights reserved.
//

#include <iostream>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#define PORT 25554
#define BACK_LOG 20  //队列允许请求数
#define BUF_SIZE 256 //  缓冲区大小
#define IP "192.168.1.5"
using std::cout;
using std::endl;

int server()
{
    int ret;
    time_t tt;
    struct tm *ttm;
    char buf[BUF_SIZE];
    pid_t pid;//定义进程描述符
    int sockfd; //
    int clientfd;
    struct sockaddr_in host_addr;
    struct sockaddr_in client_addr;
    int length=sizeof(clientfd);
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd==-1)
    {
        cout<<"服务器:创建socket失败"<<endl;
        exit(1);
    }
    bzero(&host_addr, sizeof(host_addr));
    host_addr.sin_family=AF_INET;//TCP/IP协议
    host_addr.sin_port=htons(PORT);//设置端口
    host_addr.sin_addr.s_addr=INADDR_ANY;//本地ip
    ret=bind(sockfd, (const struct sockaddr *)&host_addr, sizeof(host_addr));//绑定ip和端口
    if(ret==-1)
    {
        cout<<"服务器:bind失败"<<endl;
        exit(1);
    }
    else
    {
        cout<<"服务器:bind成功"<<endl;
    }
    //监听网络端口
    cout<<"服务器:开始监听"<<endl;
    ret=listen(sockfd, BACK_LOG);
    if(ret==-1)
    {
        cout<<"服务器:监听失败"<<endl;
        exit(1);
    }
    while (1)
    {
        /*
         倾听队列之后 accept可以从倾听套接字的完成队列里面接受一个连接,如果队列是空,进程进入睡眠状态。
         accept调用成功
         函数返回值是一个新的标识符,标识接收的连接
         第二个参数描述客户机地址 第三个描述客户机地址长度
         */
        //clientfd=accept(sockfd, (struct sockaddr *)&client_addr, &length);//接收连接请求
        //clientfd=accept(sockfd, (struct sockaddr *)&client_addr,&length);
        cout<<"服务器:准备接收"<<endl;
        clientfd = accept(sockfd, (struct sockaddr*)&client_addr, (socklen_t *)&length);
        if(clientfd==-1)
        {
            cout<<"服务器:接收失败"<<endl;
            exit(1);
        }
        pid=fork();
        if(pid==0)
        {
            while (1)
            {
                bzero(buf, sizeof(buf));
                tt=time(NULL);
                ttm=localtime(&tt);//获取当前时间参数
                strcpy(buf, asctime(ttm));// 将时间拷贝到缓冲区
                send(clientfd, buf, strlen(buf), 0);//发送数据
                sleep(2);
            }
            close(clientfd);
        }
        else if(pid>0)
        {
            close(clientfd);//父进程关闭套接字 ,准备下一个客户端连接
        }
    }
    return 0;
}
int client()
{
    int ret;
    char buf[BUF_SIZE];
    int sockfd;//套接字描述符
    struct sockaddr_in serv_addr;// 服务器端的端口号和ip
    sockfd=socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd==-1)
    {
        cout<<" 客户端:socket创建失败"<<endl;
        return 2;
    }
    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_port=htons(PORT);
    //inet_aton(IP, (struct in_addr *)&serv_addr.sin_addr.s_addr);
    serv_addr.sin_addr.s_addr=INADDR_ANY;
    cout<<"客户端:准备connect"<<endl;
    ret=connect(sockfd, (const struct sockaddr *)&serv_addr, sizeof(serv_addr));
    cout<<"客户端:connect完成"<<endl;
    if(ret==-1)
    {
        cout<<"客户端:connect失败"<<endl;
        return 3;
    }
    else
    {
        cout<<"客户端:connect success"<<endl;
    }
    while (1)
    {
        bzero(buf, sizeof(buf));
        recv(sockfd, buf, sizeof(buf), 0);
        printf("客户端:接收到数据:%s",buf);
        sleep(1);
    }
    close(sockfd);
    return 0;
}
void *thread_server(void*arg)
{
    server();
    pthread_exit(NULL);
}
void *thread_client(void*arg)
{
    client();
    pthread_exit(NULL);
}
int main(int argc, const char * argv[])
{
    cout<<"开始"<<endl;
    pthread_t thread1,thread2;
    int ret;
    ret=pthread_create(&thread2, NULL, thread_client, NULL);
    if(ret!=0)
    {
        printf("client创建失败\n");
        exit(1);
    }
    else
    {
        printf("client创建成功\n");
    }
    
    ret=pthread_create(&thread1, NULL, thread_server, NULL);
    if(ret!=0)
    {
        printf("server创建失败\n");
        exit(1);
    }
    else
    {
        printf("server创建成功\n");
    }
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/BJUT_bluecat/article/details/84985668