回声服务器

随笔3个月前发布 欢乐马
38 0 0

 //服务器端
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
 
#include<iostream>
 using namespace std;
void * thread_handleRequest(void* arg);
 
int main(void) {
 
    int sock = socket(AF_INET, SOCK_STREAM, 0);
   //socket系统建立一通信端口
   //AF_INET  Ipv4的地址     
   //SOCK_STREAM  使用tcp协议传输数据

    struct sockaddr_in server_addr;
     //sockaddr_in  表示地址和端口号
    bzero(&server_addr, sizeof(server_addr));

    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    //INADDR_ANY 所有地址  
    //htonl 将32位主机字符顺序转换成网络字符顺序
    server_addr.sin_port = htons(666);
       //htons 将16位主机字符顺序转换成网络字符顺序

 
    bind(sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
 
    listen(sock, 128);
    // 128 同时像服务器发送最多的数量
 
    printf(“wait kufuduan connenct
“);
 
    int done = 1;

    while (done) {
 
        struct sockaddr_in client;
        socklen_t  client_addr_len;
        //socklen_t  相当于 int
        client_addr_len = sizeof(client);
        int client_sock = accept(sock, (struct sockaddr *)&client, &client_addr_len);
         //等待客户端链接,,这里会阻塞程序 当有客户端链接时,客户端的地址和端口号
         //会保存在sockaddr_in client里面
         //成功返回socket 的处理代码

        char client_ip[64];
 
         cout << inet_ntop(AF_INET, &client.sin_addr.s_addr, client_ip, sizeof(client_ip))
             << endl;
        //inet_ntop 将网络字节序转换成字符串
         //返回值是字符串 同时也保存到client_ip里面
         cout << “aaaa” << client_ip << endl;
         cout << “bbbb” << ntohs(client.sin_port)<<endl;
         //ntohs 作用是将一个16位数由网络字节顺序转换为主机字节顺序
 
        //启动线程  
        {
            pthread_t tid=0;
            //pthread_t 用于声明线程ID

            int *ptr_int = NULL;
        
            cout << tid << endl;
            ptr_int = (int *)malloc(sizeof(int));
            *ptr_int = client_sock;

            pthread_create(&tid, NULL, thread_handleRequest, (void*)ptr_int);
            //成功,则返回0
            //第一个参数为指向线程标识符的指针。
            //    第二个参数用来设置线程属性。
            //    第三个参数是线程运行函数的起始地址。
            //    最后一个参数是运行函数的参数。
            cout <<“xxx” <<tid << endl;
        }
    }
    close(sock);
    return 0;
}

void * thread_handleRequest(void* arg) {
    
    cout << “hahahahahaha” << endl;

    int client_sock = *(int *)arg;
    char buf[256];
    int  i = 0;

    int len = read(client_sock, buf, sizeof(buf) – 1);
    buf[len] = '';
    cout << buf << endl;
    write(client_sock, buf, len);
    close(client_sock);
    if (arg) free(arg);
}

 

/*
linux 下 telnet 192.168.94.128 (地址) 666(端口号)
访问服务器
*/
//客户端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include<arpa/inet.h>
#include<iostream>
using namespace std;

int main () {
    struct sockaddr_in servaddr;
    memset(&servaddr, '', sizeof(struct sockaddr_in));
    //把结构体的数据清零

    servaddr.sin_family = AF_INET;
    // AF_INET: Ipv4网络协议 (Ipv4的地址 )
    servaddr.sin_port = htons(666);
    //htonl 将16位主机字符顺序转换成网络字符顺序

    inet_pton(AF_INET, “192.168.65.128”, &servaddr.sin_addr);
    //servaddr.sin_addr 保存服务器端的地址
    //inet_pton 这个函数把字符串转化成网络地址 到servaddr.sin_addr 里面

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    // AF_INET: Ipv4网络协议
    //SOCK_STREAM 使用tcp协议传输数据
    connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    // 把套接字socket 连至参数 serv_addr 指定的网络地址。
    cout << sockfd << endl;
    char message[] = “laozicaonima aaa”;
    write(sockfd, message, strlen(message));
    char buf[64];
    int n = read(sockfd, buf, sizeof(buf) – 1);
    if (n > 0) {
        buf[n] = '';
        cout << buf << endl;
    }
    close(sockfd);
    return 0;
}

/***********************************************************************************************************************************/

udb : 通信

//服务器端

#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include<unistd.h>
#include<iostream>
#include <sys/ioctl.h>
#include<fcntl.h>
using namespace std;

//服务器端  
int main(void)
{
    //int server_sockfd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK, 0);
    int server_sockfd = socket(AF_INET, SOCK_DGRAM  , 0);
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;  
    server_addr.sin_addr.s_addr = INADDR_ANY;  
    server_addr.sin_port = htons(9000);
    
    int ret = bind(server_sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if (ret == -1) {
        perror(“bind”);
        exit(1);
    }

    struct sockaddr_in client_addr;
    int client_addr_len = sizeof(struct sockaddr_in);
    cout << “waite kehuduan connect” << endl;
    
    int recv_len;
    int send_len;
    char buff[1024];
    fcntl(server_sockfd, F_SETFL, fcntl(server_sockfd, F_GETFL, 0) | O_NONBLOCK);
    // fcntl 可以改变已打开的文件性质
    /*
     1.文件句柄
     2.F_SETFL 设置文件描述符状态旗标 F_GETFL 取得文件描述符状态旗标
     3.struct flock 的指针
    */

    //ioctl(server_sockfd, FIONBIO, 0);//1非阻塞  0 阻塞
    //ubt 下不支持
    while (1) {
        //recvfrom 会堵塞直到客户端发来信息
       //客户端使用  recv
        recv_len = recvfrom(server_sockfd, buff, sizeof(buff), 0,
            (struct sockaddr*)&client_addr, (socklen_t *)&client_addr_len);
        // ssize_t recvfrom( //ssize_t==long int  socklen_t 相当于int
//成功收到的字符数,失败返回-1.
//int sockfd, 套接字
//    void *buf,  用来保存收到的数据
//    size_t len, *buf的长度
//  unsigned int flags,调用操作方式。通常设置成0
//    struct sockaddr *from, //保存发送数据来的地址
//    socklen_t *fromlen);  //*from的长度

        if (recv_len < 0) {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                sleep(2);
                cout << “hahahaha” << endl;
                continue;
            }

            cout << “recvfrom failed” << endl;
            exit(errno);

        }
        cout << “received: ” << buff << endl;

        send_len = sendto(server_sockfd, buff, strlen(buff), 0,
            (struct sockaddr*)&client_addr, client_addr_len);

        if (send_len == -1) {
            cout << “sendto failed ” << endl;
            exit(errno);
        }              
    }
    close(server_sockfd);
    return 0;
}

 

//客户端

#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <unistd.h>
#include<iostream>
using namespace std;
int main1(void)
{
    int   sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(“192.168.65.128”);
    server_addr.sin_port = htons(9000);
    char buff[1024];
    strcpy(buff, “hello world”);
    int ret = sendto(sockfd, buff, strlen(buff), 0,
        (struct sockaddr*)&server_addr, sizeof(server_addr));
/*
int sendto( //成功返回发送的字节数
socket s,   //套接字
const void * msg, // 发送的数据
int len,  // 发送数据的长度
unsigned int flags,//调用方式标志位, 一般为0, 改变flags,将会改变sendto发送的形式。
const struct sockaddr * addr, //发送的地址
int tolen); //地址结构体的长度
*/
    if (ret == -1) {
        perror(“sendto”);
        exit(errno);
    }
 
    cout << “sendto bytes is” <<ret <<endl;
    ret = recv(sockfd, buff, sizeof(buff), 0);
    if (ret == -1) {
        perror(“recvfrom”);
        cout << “recv failed” << endl;
        exit(errno);
    }
    cout << “recv bytes is” << ret << endl;
    cout << “recv contents is” << buff << endl;
    return 0;
}

 

 

 

 

 
 

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...