One of the core ideas of Linux "everything is a file"
1. For example for a local file read character string "aaaaaaa" is open () returns a handle to fd as a carrier, read and write calls to read and write
The network files and local files similar but much again to create a sockaddr_in target set protocol suite family ip address port prot front handle socket read and write data transfer some of the features with socket () returns after the sockaddr_in set a good target utilization bind () and the socket is bound; then listen () What are the biggest listening socket connection and set the number of listeners
After the above series of read and write calls can read and write, there are special: accept () connect () (setsocketopt () Set the size sendbuff and recvbuff)
2. Kernel socket is such a simple structure, the structure of which is set for each function pointer variable, or,
Each protocol to facilitate the achievement of the ultimate goal of interfaces and function names the same, but the process is different realization of the object-oriented thinking
In the Linux kernel ops is a collection of functions such as accept () connect (), etc., file there are some write () read (), etc., sk is bind () listen () and so on;
Each protocol stack interface function name is the same but the internal implementation is different
3. When creating cocket objects to tell the kernel which protocol you want to use, socket () The first parameter to add ipv4 / ipv6 protocol third parameter to add TCP / UDP protocol may be 0 (default second parameter dependent on the specific ), the second parameter, if the stream socket SOCK_ sTREAM default TCP protocol, if the packet is the UDP socket SOCK_DGRAM default, there is a raw socket SOCK_RAW using other protocols, particularly to give The third parameter
4.TCP / IP protocol
4.1 hierarchical concept: mac ip tcp
The physical layer MAC (MAC source and destination MAC length type L / T) ------> ARP to resolve link and physical connection problems
Network layer IP remote communication problems to solve
Transport layer TCP / UDP ----> port (this corresponds to a process machine) determines which process data to
Application Layer HTTP HTTPS FTP TELNET SSH
4.2 ip dotted decimal format Binary
Network byte order (big-endian) 0x12 0x34 0x56 x078 native byte order (little-endian) 0x78 0x56 0x34 0x12
case 1: dotted decimal network byte binary sequence has a dedicated function in_addr_t inet_addr (const char * cp);
case2: Binary network byte order conversion point decimal char * inet_ntoa (struct in_addr_t in);
The subnet mask is used to determine the range of 4.3 to 24 segments can be 0 ~ 255 ip address 28 can be 14 255 IP address and a broadcast address
24 == 32-bit binary 1 bits are 24 the remaining 8 bits are 0 (byte 2)
255.255.255.0 == 11111111.11111111.11111111.00000000
4.4 Unpacking and packet process
5.TCP programming principles and processes
阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回; connect 和 accept 都是阻塞函数
5.1 服务端 create socket
int sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(sock < 0) { perror("creat socket error\n"); return 1; } //sockaddr_in 设置时用 sockaddr_in 调用时强转成sockaddr struct sockaddr_in local; //设置family port ip local.sin_family = AF_INET; //htons h: honst n: network s:short 把本地端口转换成网络的 , atoi 把字符串转换成整型 ,ntohs和htons相反 local.sin_port = htons(atoi(argv[2])); local.sin_addr.s_addr = inet_addr(argv[1]); //inet_addr点分十进制转换网络二进制
bind()
if(bind(sock,(struct sockaddr*)&local,sizeof(local)) < 0) { perror("bind error\n"); close(sock); return 2; }
listen()
if(listen(sock,10) < 0){ perror("listen error\n"); close(sock); return 3; } printf("bind and listen success!wait accept...\n");
accept read write
struct sockaddr_in peer; //保存客户端信息 socklen_t len = sizeof(peer); while(1)
{ int fd = accept(sock,(struct sockaddr*)&peer ,&len); //阻塞函数 if(fd < 0){ perror("accept error\n"); close(sock); return 4; } printf("get connect,ip is : %s port is : %d\n",inet_ntoa(peer.sin_addr),ntohs(peer.sin_port)); pthread_t id; pthread_create(&id,NULL,thread_run,(void*)fd); pthread_detach(id);
}
close(sock);
void thread_run(void *arg)
{
printf("creat a new thread\n");
int fd = (int)arg;
char buf[1024];
while(1){
memset(buf,'\0',sizeof(buf));
ssize_t _s = read(fd,buf,sizeof(buf) - 1);
if(_s > 0){
buf[_s] = '\0';
printf("client say : %s\n",buf);
}
memset(buf,'\0',sizeof(buf));
printf("please Enter: ");
fflush(stdout); //清空堆里的printf内容
ssize_t _s2 = read(0,buf,sizeof(buf) - 1);
if(_s2 > 0){
write(fd,buf,strlen(buf));
}
}
}
5.2 客户端 creater socket
int sock = socket(AF_INET,SOCK_STREAM,0); if(sock < 0){ perror("socket error"); return 1; } struct sockaddr_in remote; remote.sin_family = AF_INET; remote.sin_port = htons(atoi(argv[2])); remote.sin_addr.s_addr = inet_addr(argv[1]);
connect
int ret = connect(sock,(struct sockaddr*)&remote,sizeof(remote)); if(ret < 0){ printf("connect failed:%s\n",strerror(errno)); return 2; } printf("connect success!\n");
read write
char buf[1024]; while(1){ memset(buf,'\0',sizeof(buf)); printf("please enter:"); fflush(stdout); ssize_t _s = read(0,buf,sizeof(buf)-1); if(_s > 0){ buf[_s - 1] = '\0'; write(sock,buf,strlen(buf)); _s = read(sock,buf,sizeof(buf)-1); if(_s > 0){ if(strncasecmp(buf,"quit",4) == 0){ printf("qiut\n"); break; } buf[_s -1] = '\0'; printf("%s\n",buf); } } } close(sock);