1. TCP和UDP通信模型
1.1 TCP server
#include <myhead.h>
#define PORT 9999
#define IP "192.168.250.100"
int main(int argc, const char *argv[])
{
//1. create socket
int sfd = -1;
if( (sfd = socket(AF_INET, SOCK_STREAM, 0 ))==-1 )
{
perror("socket error");
return -1;
}
//param1: AF_INET -->ipv4 domain
//param2: AF_INET --> tcp protocal
//param3; if param2 has specified only protocal, fill 0
//returned: On success, a file descriptor for the new socket is returned. On error, -1 is returned, and errno is set appropriately.
printf("sfd = %d\n", sfd);
//2. bind address info struct
struct sockaddr_in sin;
sin.sin_family = AF_INET; //ipv4
sin.sin_port = htons(PORT); // htons --> port in network bytes order
sin.sin_addr.s_addr = inet_addr(IP); //inet_addr--> address in network bytes order
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1 )
{
perror("bind error");
return -1;
}
//assigns the address specified by addr to the socket referred to by the file descriptor sockfd.
//addrlen specifies the size, in bytes, of the address structure pointed to by addr.
printf("bind success _%d_%s_%s\n", __LINE__, __FILE__, __func__);
//3. listen()
if( listen(sfd, 128) ==-1 )
{
perror("listen error");
return -1;
}
//listen() marks the socket referred to by sockfd as a passive socket,
//that is, as a socket that will be used to accept incoming connection requests using accept(2).
printf("listen success _%d_%s_%s\n", __LINE__, __FILE__, __func__);
//4. accept
/*if(accept(sfd, NULL, NULL) == -1 ) // NULL, NULL means skip client info
{
perror("accept error");
return -1;
}
printf("accept success _%d_%s_%s\n", __LINE__, __FILE__, __func__);
*/
// 4.1 accept, recv client info
// define client info struct
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin);
//4.2 recv client requests
int newfd = -1;
if( (newfd = accept(sfd, (struct sockaddr*)&cin, &socklen)) == -1 )
{
perror("accept error");
return -1;
}
printf("[%s:%d] accept success, newfd = %d\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
//5. data send/recv
char rbuf[128] = "";
while(1)
{
//clean buf
bzero(rbuf, sizeof(rbuf));
int res = recv(newfd, rbuf, sizeof(rbuf), 0);
//param1: file descriptor
//param2: buff
//param3: size
//param4: block
if(res == 0)
{
printf("client off line\n");
break;
}
printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), rbuf);
//send back msg to clinet
strcpy(rbuf, "\n*_*\n");
send(newfd, rbuf, sizeof(rbuf), 0);
}
close(newfd);
close(sfd);
return 0;
}
1.2 TCP client
#include <myhead.h>
#define PORTSVC 9999
#define IPSVC "192.168.250.100"
#define PORTCLI 6666
#define IPCLI "192.168.250.100"
int main(int argc, const char *argv[])
{
//1. create socket
int cfd = -1;
if( (cfd = socket(AF_INET, SOCK_STREAM, 0))==-1 )
{
perror("socket error");
return -1;
}
printf("cfd = %d\n", cfd);
//端口号快速重用
int reuse = -1;
if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
{
perror("setsockopt error");
return -1;
}
//2. binding
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_port = htons(PORTCLI);
cin.sin_addr.s_addr = inet_addr(IPCLI);
if(bind(cfd, (struct sockaddr *)&cin, sizeof(cin)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3. connect server
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORTSVC);
sin.sin_addr.s_addr = inet_addr(IPSVC);
if( connect(cfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
perror("connect error");
return -1;
}
//4. data send/recv
char wbuf[128] = "";
while(1)
{
bzero(wbuf, sizeof(wbuf));
//input text
fgets(wbuf, sizeof(wbuf), stdin);
wbuf[strlen(wbuf) - 1] = 0;
if(strcmp(wbuf, "quit") == 0)
{
printf("exit client\n");
break;
}
//send data to svc
send(cfd, wbuf, sizeof(wbuf), 0);
//data recv
bzero(wbuf, sizeof(wbuf));
int res = recv(cfd, wbuf, sizeof(wbuf), 0);
if(res == 0)
{
printf("server is off line\n");
break;
}
printf("[%s:%d]: %s\n", IPSVC, PORTSVC, wbuf);
}
close(cfd);
return 0;
}
2.1 upd server
#include <myhead.h>
#define PORT 9999
#define IP "192.168.250.100"
int main(int argc, const char *argv[])
{
//1. create socket
int sfd = -1;
if( (sfd=socket(AF_INET, SOCK_DGRAM, 0 )) == -1 )
{
perror("socket error");
return -1;
}
printf("sfd=%d\n", sfd);
// port resue
int reuse = 1;
if( setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1 )
{
perror("setsockopt error");
return -1;
}
//3. bind IP
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
if(bind(sfd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
{
perror("setsockopt error");
return -1;
}
printf("bind success\n");
//4. data recv/send
char buf[128] = "";
//addr struct
struct sockaddr_in cin;
socklen_t socklen = sizeof(cin);
while(1)
{
bzero(buf, sizeof(buf));
recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &socklen);
printf("[%s:%d]: %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
//feedback to clinet
strcpy(buf, "*_*");
sendto(sfd, buf, sizeof(buf), 0, (struct sockaddr *)&cin, sizeof(cin) );
printf("send success\n");
}
close(sfd);
return 0;
}
2.2 upd client
#include <myhead.h>
#define PORT 9999
#define IP "192.168.250.100"
int main(int argc, const char *argv[])
{
//1. create socket
int cfd =-1;
if( (cfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1 )
{
perror("socket error");
return -1;
}
printf("cfd = %d\n", cfd);
//2. binding ip, optional
//3. define addr struct for data sending
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT);
sin.sin_addr.s_addr = inet_addr(IP);
char buf[128] = "";
//struct sockaddr_in cin;
//socklen_t socklen = sizeof(cin);
while(1)
{
bzero(buf, sizeof(buf));
// send data to server
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf) - 1] = 0;
sendto(cfd, buf, sizeof(buf), 0, (struct sockaddr *)&sin, sizeof(sin));
//recv data from server
recvfrom(cfd, buf, sizeof(buf), 0, NULL, NULL );
printf("msg from svc: %s\n", buf);
}
return 0;
}
2. 思维导图