Socket learning day2_renew
tcp three-way handshake and four-way handshake
- the three-way handshake
server function Listen()
1.SYN: x(0) (c->s)
SYN:the serial number;
client status: SYN_SENT function:Connect()
2.SYN: y ACK: x+1 (s->c)
ACK:the last SYN add 1
server status: SYN_RCVD
client status: ESTABLISHED
3.ACK: y+1 (c->s)
ACK:the last SYN add 1
server status: ESTABLISHED
- the data transmission
1.Seq: x+1 (1) ACK: y+1 (c->s)
Seq:the serial data
2.ACK: x+2 (s->c)
ACK:the last Seq add 1
- the cutdown of connection
client status: FIN_WAIT_1
client function: Close()
1.FIN:x+2 ACK:y+1 (c->s)
server status: CLOSE_WAIT
2.ACK:x+3 (s->c)
client status: FIN_WAIT_2
3.FIN:y+1 ACK:x+3(s->c)
server status: LAST_ACK
client status: TIME_WAIT
4.ACK:y+2(c->s)
server status: CLOSED
TIME_WAIT is appear at the active close
the code of socket_server by multiply process
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<ctype.h>
#include<signal.h>
#include "wrap.h"
void waitchild(int signo){
pid_t wpid;
while(1){
wpid = waitpid(-1, NULL, WNOHANG);
if(wpid > 0){
printf("child exit, wpid = %d\n", wpid);
}else if(wpid == 0 || wpid == -1){
break;
}
}
}
int main(){
//1.build socket
int lfd = Socket(AF_INET, SOCK_STREAM, 0);
//ps:reuse the port
int opt = 1;
setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int));
//2.bind the socket
struct sockaddr_in serv;
serv.sin_family = AF_INET;
serv.sin_port = htons(8888);
serv.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(lfd, (struct sockaddr *)&serv, sizeof(serv));
//3.listen the client
Listen(lfd, 128);
//block SIGCHLD signal
sigset_t mask;
sigemptyset(&mask);
sigaddset(&mask, SIGCHLD);
sigprocmask(SIG_BLOCK, &mask, NULL);
int cfd;
pid_t pid;
struct sockaddr_in client;
int len;
char sIP[16];//record the ip of client
while(1){
len = sizeof(client);
memset(sIP, 0x00, sizeof(sIP));
//accept the client request
cfd = Accept(lfd, (struct sockaddr *)&client, &len);
printf("client port==%d ip==%s\n", ntohs(client.sin_port), inet_ntop(AF_INET, &client.sin_addr.s_addr, sIP, sizeof(sIP)));
//make a son process to handle the data
pid = fork();
if(pid < 0){
perror("fork error");
exit(-1);
}else if(pid > 0){
//close the cfd
close(cfd);
// waitchild(waitpid : recovery the resources) unblock the SIGCHLD
struct sigaction act;
act.sa_handler = waitchild;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(SIGCHLD, &act, NULL);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
}else if(pid == 0){
//close the lfd
close(lfd);
int i;
int n;
char buf[1024];
//memset(buf, 0x00, sizeof(buf));
while(1){
n = Read(cfd, buf, sizeof(buf));
if(n <= 0){
printf("read error or client closed,n==%d",n);
break;
}
printf("client port==%d, n==%d, buf==%s\n", ntohs(client.sin_port), n, buf);
for(i = 0; i < n; i++){
buf[i] = toupper(buf[i]);
}
Write(cfd, buf, n);
}
close(cfd);
exit(0);
}
}
close(lfd);
return 0;
}
Write(cfd, buf, n);
}
close(cfd);
exit(0);
}
}
close(lfd);
return 0;
}