网络编程学习1:套接字socket

本文详细介绍了网络编程中的套接字五元组,包括其在TCP和UDP中的作用,以及如何通过socket、connect、getsockname和getpeername等函数操作套接字。此外,还探讨了SO_REUSEADDR选项在TCP和UDP中的不同影响,并讨论了在NAT穿透场景下的应用。
摘要由CSDN通过智能技术生成

套接字的五元组{protocol,src_addr,src_port,dest_addr,dest_port}

五元组很重要啊!!!

https://blog.csdn.net/myhes/article/details/108318908

如何确定一个链接?或者说系统如何区分这么多链接(10k)?五元组唯一确定一个链接。

 

下面说说几个函数

socket函数

#include <sys/socket.h>
int socket(int family, int type, int protocol);//成功返回非负数,失败返回-1
//tcp family=AF_INET, type=SOCK_STREAM, protocol=IPPROTO_TCP/0
//udp family=AF_INET, type=SOCK_DGRAM, protocol=IPPROTO_UDP/0
//其他组合可参考《网络编程 卷1:套接字联网API》

connect函数

#include <sys/socket.h>
int connect(int sockfd,const struct sockaddr* servaddr,socklen_t addrlen);//成功0,失败-1

对于tcp而言,connect包含了:三次握手 + setpeername,只能调用一次。

对于udp而言,connect包含了:setpeername,可以调用多次。

对udp调用connect之后,只能改用send/recv。在性能上connect后调用send/recv比sendto/recvfrom更高。

 

getsockname和getpeername函数

#include <sys/socket.h>

int getsockname(int sockfd,struct sockaddr* localaddr,socklen_t *addrlen);//成功0,失败-1
int getpeername(int sockfd,struct sockaddr* peeraddr,socklen_t *addrlen);//成功0,失败-1

getsockname用法:

1、在一个没有调用bind的tcp客户端上,connect成功后,调用getsockname获取内核赋予该链接的本地IP地址和端口。

2、tcp客户端以端口号0(或者指定端口)调用bind后,调用getsockname获取内核赋予该链接的本地IP地址和端口。

getpeername用法:

1、tcp客户端connect连接成功后,调用getpeername获取服务端的IP地址和端口。

2、tcp服务端accept成功后,调用getpeername获取客户端的IP地址和端口。

 

 

tcp_server.c

#include <stdio.h>
#include <string.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <errno.h>

void show(int sockfd,char* sockname){
    //getsockname(sockfd,(struct sockaddr*)&client_addr,&client_addr_len)
    //getpeername(sockfd,(struct sockaddr*)&server_addr,&server_addr_len)
}


int main(){
    int server_sockfd,client_sockfd;
    server_sockfd = socket(AF_INET,SOCK_STREAM,0);

    struct sockaddr_in client_addr,server_addr;
    socklen_t client_addr_len = sizeof(client_addr),server_addr_len = sizeof(server_addr);

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(9999);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(bind(server_sockfd,(struct sockaddr*)&server_addr,sizeof(server_addr)) < 0){
        printf("%d %d %s\n",__LINE__,errno,strerror(errno));
    }

    show(server_sockfd,"server");
    //server getsockname 127.0.0.1:9999
    //server getpeername fail 107 Transport endpoint is not connected

    listen(server_sockfd,5);

    client_sockfd = accept(server_sockfd,(struct sockaddr*)&client_addr,&client_addr_len) ;

    show(server_sockfd,"server");
    //ser
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值