思维导图
TCP服务器端和客户端通讯
服务器端 代码
#include<myhead.h>
#define SER_IP "192.168.109.12"//我的虚拟机的ip
#define SER_PORT 8888
int main()
{
//1.创建一个用于连接的套接字文件描述符
int sfd = socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket error");
return -1;
}
printf("sfd = %d\n",sfd);
//2.给套接字绑定ip地址和的端口号
//2.1准备地址信息结构体
struct sockaddr_in sin;
//通信域地址族
sin.sin_family = AF_INET;
//服务器端口号
sin.sin_port = htons(SER_PORT);//2字节 主机字节序 转化为 网络字节序
//服务器ip地址
sin.sin_addr.s_addr = inet_addr(SER_IP);//ip地址 点分十进制 转化为 网络字节序
//2.2执行绑定工作
if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
//3.将套接字设置成被动监听状态
if(listen(sfd,128)==-1)
{
perror("listen error");
return -1;
}
printf("listen success\n");
//4.阻塞 等客户端的连接
//4.1 定义地址信息结构体,用于客户端地址信息
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin);//接收地址长度
int newfd = accept(sfd,(struct sockaddr*)&cin,&addrlen);
if(newfd==-1)
{
perror("accept error");
return -1;
}
printf("[%s:%d]-连接成功newfd = %d\n",\
inet_ntoa(cin.sin_addr),\
ntohs(cin.sin_port),newfd);
//5.实现数据的收发
char buf[128]="";
while(1)
{
//清空buf
bzero(buf,sizeof(buf));
//从套接字读取消息
int res=read(newfd,buf,sizeof(buf));
if(res==0)
{
printf("客户端下线\n");
close(newfd);//关闭通信套接字
break;
}
printf("[%s:%d] : %s\n",\
inet_ntoa(cin.sin_addr),\
ntohs(cin.sin_port),buf);
//给消息 加个:D还回去
strcat(buf,":D");
write(newfd,buf,strlen(buf));
printf("发送成功\n");
}
//6.关闭套接字
close(sfd);
return 0;
}
客户端 代码
#include<myhead.h>
#define SER_IP "192.168.109.12" //服务器ip地址
#define SER_PORT 8888 //服务器端口号
#define CLI_IP "192.168.109.12" //客户端ip地址
#define CLI_PORT 7777 //客户端端口号
int main(int argc, const char *argv[])
{
//1、创建用于通信的套接字文件描述符
int cfd = socket(AF_INET, SOCK_STREAM, 0);
if(cfd == -1)
{
perror("socket error");
return -1;
}
//2、给客户端套接字绑定ip地址和端口号
//2.1 填充地址信息结构体
struct sockaddr_in cin;
cin.sin_family = AF_INET;
cin.sin_addr.s_addr = inet_addr(CLI_IP);
cin.sin_port = htons(CLI_PORT);
//2.2 绑定
if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin))==-1)
{
perror("bind error");
return -1;
}
//3、连接服务器
//3.1 组装对端地址信息结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET; //通信域
sin.sin_addr.s_addr = inet_addr(SER_IP); //要连接的服务器ip
sin.sin_port = htons(SER_PORT); //服务器的端口号
//3.2 连接操作
if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin))==-1)
{
perror("connect error");
return -1;
}
//4、数据通信
char buf[128] = "";
while(1)
{
//从终端输入要发送的消息
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = 0;
//判断输入内容
if(strcmp(buf, "quit")==0)
{
break;
}
//将消息发送给服务器
write(cfd, buf, strlen(buf));
printf("发送成功\n");
//接受服务器发来的消息
bzero(buf, sizeof(buf));
int res = read(cfd, buf, sizeof(buf));
if(res == 0)
{
printf("服务器已经下线\n");
break;
}
printf("收到服务器消息:%s\n", buf);
}
//5、关闭套接字
close(cfd);
return 0;
}
运行
UDP服务器和客户端通讯
服务器代码
#include<myhead.h>
#define SER_IP "192.168.109.12"
#define SER_PORT 8888
/*****************主程序*****************/
int main(int argc, const char *argv[])
{
//1、创建一个用于通信的套接字文件描述符
int sfd = socket(AF_INET, SOCK_DGRAM, 0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
//2、绑定ip地址和端口号(必须)
//2.1 封装结构体
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr(SER_IP);
sin.sin_port = htons(SER_PORT);
//2.2 绑定
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))==-1)
{
perror("bind error");
return -1;
}
//3、数据收发
char buf[128] = ""; //用于接受对端消息
//定义一个地址信息结构体的变量,用于接收对端地址
struct sockaddr_in cin;
socklen_t addrlen = sizeof(cin); //接受地址长度
while(1)
{
//清空容器
bzero(buf, sizeof(buf));
//从套接字文件描述符中读取消息
recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&cin, &addrlen);
printf("[%s:%d] : %s\n",
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
//给消息加个笑脸还回去
strcat(buf, ":D");
//发送消息
sendto(sfd, buf, strlen(buf), 0, (struct sockaddr*)&cin, sizeof(cin));
printf("发送成功\n");
}
//4、关闭套接字
close(sfd);
return 0;
}
客户端代码
#include<myhead.h>
#define SER_IP "192.168.109.12"
#define SER_PORT 8888
/******************主程序******************/
int main(int argc, const char *argv[])
{
//1、创建一个用于通信的套接字文件描述符
int cfd = socket(AF_INET, SOCK_DGRAM, 0);
if(cfd == -1)
{
perror("socket error");
return -1;
}
//2、绑定ip和端口号(可选)
//3、数据收发
char buf[128] = ""; //数据容器
struct sockaddr_in sin; //目标地址
sin.sin_family = AF_INET;
sin.sin_port = htons(SER_PORT);
sin.sin_addr.s_addr = inet_addr(SER_IP);
socklen_t addrlen = sizeof(sin);
while(1)
{
//清空容器
bzero(buf, sizeof(buf));
fgets(buf, sizeof(buf), stdin); //从终端获取数据
buf[strlen(buf)-1] = 0;
if(strcmp(buf,"quit")==0)
{
break;
}
//将数据发送给服务器
sendto(cfd, buf, strlen(buf), 0, (struct sockaddr*)&sin, sizeof(sin));
printf("发送成功\n");
//接收服务器发来的消息
bzero(buf, sizeof(buf));
//recvfrom(cfd, buf, sizeof(buf), 0, (struct socket*)&sin, &addrlen);
//recvfrom(cfd, buf, sizeof(buf), 0, NULL,NULL);
read(cfd, buf, sizeof(buf));
printf("收到服务器消息为:%s\n", buf);
}
//4、关闭套接字
close(cfd);
return 0;
}
运行情况
牛客