1.思维导图
2.TCP通信模型的实现
服务器端
#include <head.h>
#define SERVER_IP "192.168.125.223"
#define SERVER_PORT 8888
/*
*第一步,调用socket函数,为服务器开辟一个通信端点
*第二步,在服务器通信端点地址信息结构体(struct sockaddr_in)中,设置服务器通信端点相关信息
* struct sockaddr_in
* {
* sa_family_t(unsigned short int) sin_family--->协议族,即使用的通信协议
* struct in_addr sin_addr --->服务器的IP地址
* in_port_t(unsigned short int) sin_port --->服务器通信端点的端口号
* }
* struct in_addr
* {
* uint32_t(unsigned int) s_addr
* }
*第三步,调用bind函数,绑定服务器通信端点信息
*第四步,调用listen函数,监听服务器通信端点是否有客户端连接服务器请求
*第五步,调用accept函数,等待响应客户端连接服务器请求,即开辟一个与当前通信端点地址信息完全一样的新通信端点供二者进行信息交互,同时有选择的接收客户端的地址信息
*第六步,与客户端进行信息交互
*/
int main(int argc,const char* argv[])
{
while(1)
{
//① 创建服务器通信端点
int server_socket_fd=socket(AF_INET,SOCK_STREAM,0);
if(server_socket_fd==-1)
{
perror("server_socket");
return -1;
}
printf("create server socket success\n");
//② 设置端口号快速重用
int reuse =1;
if(setsockopt(server_socket_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt");
return -2;
}
printf("setsockopt success\n");
//③ 设置服务器通信端点相关信息,即为服务器通信端点地址信息结构体赋值
struct sockaddr_in server_sin;
server_sin.sin_family = AF_INET;
server_sin.sin_port = htons(SERVER_PORT);
server_sin.sin_addr.s_addr = inet_addr(SERVER_IP);
//④ 绑定服务器通信端点信息
if(bind(server_socket_fd,(struct sockaddr*)&server_sin,sizeof(server_sin))==-1)
{
perror("server_bind");
return -3;
}
printf("bind server socket success\n");
//⑤ 将当前服务器通信端点设置成监听模式,监听服务器通信端点是否有客户端连接服务器请求
if(listen(server_socket_fd,128)==-1)
{
perror("liten");
return -4;
}
printf("set listen mode success\n");
printf("lisening……\n");
struct sockaddr_in client_sin;
socklen_t client_sin_len = sizeof(client_sin);
//⑥ 阻塞等待客户端的连接请求,开辟一个与当前服务器通信端点信息相同的新服务器通信端点,同时有选择的接收客户端的通信端点信息
int server_socket_new_fd=accept(server_socket_fd,(struct sockaddr*)&client_sin,&client_sin_len);
if(server_socket_new_fd==-1)
{
perror("server_accept");
return -5;
}
printf("[%s:%d]:已连接\n",inet_ntoa(client_sin.sin_addr),ntohs(client_sin.sin_port));
//⑦ 与客户端进行信息交互
char rec_buff[256];
while(1)
{
memset(rec_buff,0,sizeof(rec_buff));
recv(server_socket_new_fd,rec_buff,sizeof(rec_buff),0);
if(strcmp(rec_buff,"exit")!=0/*&&*rec_buff!=0*/)
{
printf("[%s:%d]:%s\n",inet_ntoa(client_sin.sin_addr),ntohs(client_sin.sin_port),rec_buff);
strcat(rec_buff,"^_^");
send(server_socket_new_fd,rec_buff,sizeof(rec_buff),0);
printf("发送成功\n");
}
else if(strcmp(rec_buff,"exit")==0)
{
printf("[%s:%d]:退出连接\n",inet_ntoa(client_sin.sin_addr),ntohs(client_sin.sin_port));
break;
}
}
close(server_socket_new_fd);
close(server_socket_fd);
}
return 0;
}
客户端
#include <head.h>
#define SERVER_IP "192.168.125.223"
#define SERVER_PORT 8888
#define CLIENT_IP "192.168.125.223"
#define CLIENT_PORT 6789
int main(int argc, const char *argv[])
{
//① 创建客户端通信端点
int client_socket_fd=socket(AF_INET,SOCK_STREAM,0);
if(client_socket_fd==-1)
{
perror("client_socket");
return -1;
}
printf("create client socket success\n");
//② 设置端口号快速重用
int reuse =1;
if(setsockopt(client_socket_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1)
{
perror("setsockopt");
return -2;
}
printf("setsockopt success\n");
//③ 设置客户端通信端点相关信息,即为客户端通信端点地址信息结构体赋值
struct sockaddr_in client_sin;
client_sin.sin_family = AF_INET;
client_sin.sin_port = htons(CLIENT_PORT);
client_sin.sin_addr.s_addr = inet_addr(CLIENT_IP);
//④ 绑定客户端通信端点信息
if(bind(client_socket_fd,(struct sockaddr*)&client_sin,sizeof(client_sin))==-1)
{
perror("client_bind");
return -3;
}
printf("bind client socket success\n");
//⑤ 设置服务器通信端点相关信息,即为服务器通信端点地址信息结构体赋值
struct sockaddr_in server_sin;
server_sin.sin_family = AF_INET;
server_sin.sin_port = htons(SERVER_PORT);
server_sin.sin_addr.s_addr = inet_addr(SERVER_IP);
//⑥ 向服务器通信端点发送连接请求
if(connect(client_socket_fd,(struct sockaddr*)&server_sin,sizeof(server_sin))==-1)
{
perror("connect_server");
return -4;
}
printf("client socket connect server socket success\n");
//⑦ 与服务器进行信息交互
char wbuff[256];
char rbuff[256];
while(1)
{
printf("请输入发送信息\n");
memset(wbuff,0,sizeof(wbuff));
fgets(wbuff,sizeof(wbuff),stdin);
wbuff[strlen(wbuff)-1]='\0';
write(client_socket_fd,wbuff,strlen(wbuff));
if(strcmp(wbuff,"exit")==0)
{
break;
}
memset(rbuff,0,sizeof(rbuff));
read(client_socket_fd,rbuff,sizeof(rbuff));
printf("[%s:%d]:%s\n",inet_ntoa(server_sin.sin_addr),ntohs(server_sin.sin_port),rbuff);
}
close(client_socket_fd);
return 0;
}
3.UDP通信模型
服务器端
#include <head.h>
#define SERVER_IP "192.168.125.223"
#define SERVER_PORT 8888
int main(int argc, const char *argv[])
{
int server_sock_fd=socket(AF_INET,SOCK_DGRAM,0);
if(server_sock_fd==-1)
{
perror("server_socket");
return -1;
}
struct sockaddr_in server_sin;
server_sin.sin_family = AF_INET;
server_sin.sin_port = htons(SERVER_PORT);
server_sin.sin_addr.s_addr = inet_addr(SERVER_IP);
if(bind(server_sock_fd,(struct sockaddr*)&server_sin,sizeof(server_sin))==-1)
{
perror("server_bind");
return -2;
}
printf("server bind success\n");
char rbuff[256];
struct sockaddr_in user_sin;
socklen_t user_sin_len=sizeof(user_sin);
while(1)
{
memset(rbuff,0,sizeof(rbuff));
recvfrom(server_sock_fd,rbuff,sizeof(rbuff),0,(struct sockaddr*)&user_sin,&user_sin_len);
if(strcmp(rbuff,"exit")!=0)
{
printf("C[%s:%d]:%s\n",inet_ntoa(user_sin.sin_addr),ntohs(user_sin.sin_port),rbuff);
strcat(rbuff,"^-^");
sendto(server_sock_fd,rbuff,sizeof(rbuff),0,(struct sockaddr*)&user_sin,sizeof(user_sin));
printf("发送成功\n");
}
}
close(server_sock_fd);
return 0;
}
客户端
#include <head.h>
#define SERVER_IP "192.168.125.223"
#define SERVER_PORT 8888
#define CLIENT_IP "192.168.125.223"
#define CLIENT_PORT 9999
int main(int argc, const char *argv[])
{
int client_sock_fd=socket(AF_INET,SOCK_DGRAM,0);
if(client_sock_fd==-1)
{
perror("client socket");
return -1;
}
struct sockaddr_in client_sin;
client_sin.sin_family = AF_INET;
client_sin.sin_port = htons(CLIENT_PORT);
client_sin.sin_addr.s_addr = inet_addr(CLIENT_IP);
if(bind(client_sock_fd,(struct sockaddr*)&client_sin,sizeof(client_sin))==-1)
{
perror("client_bind");
return -2;
}
printf("client bind success\n");
struct sockaddr_in server_sin;
server_sin.sin_family = AF_INET;
server_sin.sin_port = htons(SERVER_PORT);
server_sin.sin_addr.s_addr = inet_addr(SERVER_IP);
char wbuff[256];
while(1)
{
memset(wbuff,0,sizeof(wbuff));
printf("请输入>>>>");
fgets(wbuff,sizeof(wbuff),stdin);
wbuff[strlen(wbuff)-1]='\0';
if(strcmp(wbuff,"exit")==0)
{
break;
}
sendto(client_sock_fd,wbuff,sizeof(wbuff),0,(struct sockaddr*)&server_sin,sizeof(server_sin));
recvfrom(client_sock_fd,wbuff,sizeof(wbuff),0,NULL,NULL);
printf("S[%s:%d]:%s\n",inet_ntoa(server_sin.sin_addr),ntohs(server_sin.sin_port),wbuff);
}
close(client_sock_fd);
return 0;
}