套接字的五元组{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