您的位置:首页 > 理论基础 > 计算机网络

TCP/UDP socket编程学习

2017-08-15 09:05 239 查看
一、SOCKET编程

创建一个传输终端:socket

函数原型:int socket(int domain, int type, int protocol);

头文件:sys/types.h sys/socket.h

成功:返回新的socket文件描述符  失败:-1

domain:协议类型

type:socket类型

protocol:选择特定协议,默认为0.

绑定地址(绑定网卡):bind

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

头文件:sys/types.h sys/socket.h

成功:返回0 失败:-1

sockfd:socket文件描述符

addr:socket的结构地址

addrlen:地址的长度

设置监听:listen

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

头文件: sys/types.h sys/socket.h

成功:返回0 失败: -1

sockfd:socket文件描述符

backlog:表示高进程所要入队的连接请求数量

等待连接:accept

函数原型: int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

头文件:sys/types.h sys/socket.h
成功:返回接受后新的描述符 失败: -1

sockfd:socket文件描述符

addr:socket的结构地址

*addrlen:地址的长度的指针

发送消息:send

函数原型:ssize_t send(int sockfd, const void *buf, size_t len, int flags);

头文件: sys/types.h sys/socket.h

成功:返回发送的数量 失败:-1
sockfd:ssocket文件描述符

*buf:需要发送的内容

len:需要发送的长度

flags:发送标识符(不同于write的区别)

连接服务器:connect

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

头文件: sys/types.h sys/socket.h

成功:0 失败:-1

sockfd:ssocket文件描述符
addr:socket的结构地址
addrlen:地址的长度

二、地址类型

struct sockaddr{

    sa_family_t sa_family;       通用的地址,协议族

    char sa_data[14];            

}

这个用来IPv4地址类型:

struct sockaddr_in{

    short int sin_family;

    unsigned short int sin_port;

    struct in_addr sin_addr;

    unsigned char sin_zero[8];

}

struct in_addr{

    unsigned long s_addr;

}



三、地址转换
地址转化:inet_addr  将字符串形式的IP地址转化为整数型的IP地址(网络字节序)
函数原型:in_addr_t inet_addr(const char *cp);
头文件:sys/socket.h netinet/in.h  arpa/inet.h
成功:返回0 失败:-1
sockfd:socket文件描述符
addr:socket的结构地址
addrlen:地址的长度

地址转化(反): innet_ntoa

函数原型: char *inet_ntoa(struct in_addr in);

头文件:sys/socket.h netinet/in.h arpa/inet.h

成功:返回字符串 

in:需要转换的in_addr结构的地址

四、网络字节序

如果两台设备进行通信,一台是小端模式的,一台是大端模式的。那么如果没有统一的结构,小端发送的字节序列通过网络发送到大端后,再有大端设备读取出来可能内容有偏差。
网络上传输的都是用大端模式的。

uint32_t htonl(uint32_t hostlong);

将32位的数据从主机字节序转换为网络字节序。 in_addr.saddr = htonl(INADDR_ANY)

uint16_t htons(uint16_t hostshort);
将16位的数据从主机字节序转换为网络字节序

uint32_t ntohl(uint32_t netlong);
将32位的数据从网络字节序转换为主机字节序

uint16_t ntohs(uint16_t netshort);
将16位的数据从网络字节序转换为主机字节序

五、TCP通讯程序设计

tcp_server.c:

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <strings.h>

//#include <netinet/in.h>

#include <arpa/inet.h>

#define portnum 3333

int main()

{

    int sockfd;

    int new_fd;

    struct sockaddr_in server_addr;

    struct sockaddr_in client_addr;

    char buffer[128];

    int nbyte = 0;

    int sin_size;

    /*1.创建socket*/

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

         printf("create socket error!\n");

         exit(1);

    }

    /*2.1设置要绑定的地址*/

    bzero(&server_addr, sizeof(struct sockaddr_in));

    server_addr.sin_family = AF_INET;

    server_addr.sin_port = htons(portnum);

    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    /*2.2.绑定地址*/

    bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

    /*3.监听端口*/

    listen(sockfd, 5);

    while(1)

    {

    /*4.等待链接*/

        sin_size = sizeof(struct sockaddr);

        new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);

        if(new_fd == -1)

        {

            printf("accept socket failed\n");

            exit(1);

        }

        

        printf("server get connection form %s\n", inet_ntoa(client_addr.sin_addr));

        /*5.接收数据*/

        nbyte = recv(new_fd, buffer, 128, 0);

        buffer[nbyte] = '\0';

        printf("server received : %s\n",buffer);

    /*6.结束链接*/

        close(new_fd);

    }

    close(sockfd);

    return 0;

}

tcp_client:

#include <sys/types.h>

#include <sys/socket.h>

#include <stdio.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

#define portnum 3333

int main()

{

    struct sockaddr_in server_addr;

    int sockfd;

    char buffer[128];

    /*1.创建socket*/

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

    {

        printf("create socket error!\n");

        exit(1);

    }

    /*2.1设置要绑定的地址*/

    bzero(&server_addr, sizeof(struct sockaddr_in));

    server_addr.sin_family = AF_INET;

    server_addr.sin_port = htons(portnum);

    server_addr.sin_addr.s_addr = inet_addr("192.168.1.110");

 

    /*2.链接服务器*/

    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)) == -1)

    {

        printf("connect error!\n");

        exit(1);

    }

    /*3.发送数据到服务器*/

    printf("please input char:\n");

    fgets(buffer,128,stdin);

    send(sockfd, buffer, strlen(buffer), 0);

    /*4.结束连接*/

    close(sockfd);

}

六、UDP编程练习

udp_server.c:

#include <sys/types.h>

#include <sys/socket.h>

#include <strings.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <unistd.h>

#define portnum 3333

#define MSG_SIZE 128

int main()

{

    int sockfd;

    struct sockaddr_in server_addr;

    struct sockaddr_in client_addr;

    char buffer[MSG_SIZE];

    int addrlen;

    int n;

    /*创建socket*/

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)

    {

        printf("create socket error!\n");

    exit(1);

    }

    

    bzero(&server_addr, sizeof(struct sockaddr_in));

    server_addr.sin_family = AF_INET;

    server_addr.sin_port = htons(portnum);

    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    /*绑定地址*/

    bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

    

    /*接收数据*/

    while(1)

    {

        addrlen = sizeof(struct sockaddr);

    bzero(buffer, MSG_SIZE);

        n = recvfrom(sockfd, buffer, MSG_SIZE, 0, (struct sockaddr *)&client_addr, &addrlen);

    buffer[n] = '\0';

    printf("server received :%s\n", buffer);

    }

    /*结束连接*/

    close(sockfd);

    return 0;

}

udp_client.c:

#include <strings.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <strings.h>

#include <stdio.h>

#include <arpa/inet.h>

#define portnum 3333

#define BUF_SIZE 128

int main(int argc, char *argv[])

{

    int sockfd;

    char buffer[BUF_SIZE];

    struct sockaddr_in server_addr;

    if(argc != 2)

    {

        printf("Usage: ./udp_client [ip]\n");

    exit(0);

    }

    /*创建socket*/

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)

    {

        printf("create socket failed!\n");

        exit(1);

    }

    /*发送数据*/

    bzero(&server_addr, sizeof(struct sockaddr_in));

    server_addr.sin_family = AF_INET;

    server_addr.sin_port = htons(portnum);

    inet_aton(argv[1], &server_addr.sin_addr);

    while(1)

    {

        printf("Please input char:\n");

    fgets(buffer, BUF_SIZE, stdin);

        sendto(sockfd, buffer, BUF_SIZE, 0, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));

    bzero(buffer, BUF_SIZE);

    }

    /*结束链接*/

    close(sockfd);

}


<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>

阅读(66) | 评论(0) | 转发(0) |

0
上一篇:Linux网络编程协议

下一篇:vim多行增加缩进

相关热门文章
test123

编写安全代码——小心有符号数...

使用openssl api进行加密解密...

一段自己打印自己的c程序...

彻底搞定C语言指针详解-完整版...

给主人留下些什么吧!~~

评论热议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: