目的:基于socket的简单TCP通信实例
TCP通信流程图:
代码:my_recv.c my_send.c
my_recv.c
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
int sfd_listen;
//1.生成一个套接口描述符
sfd_listen=socket(AF_INET,SOCK_STREAM,0);
if(sfd_listen==-1)//判断
{
perror("socket");
exit(-1);
}
//2. 将套接口与指定的ip地址和端口号相关联,ip+端口号就是套接口
struct sockaddr_in my_addr;
/*
struct sockaddr_in
{
unsigned short int sin_family;
uint16_t sin_port;//定义端口号,可以直接指定,也可由系统指定,也是网络字节序,一般用htons()函数转换。
struct in_addr sin_addr;//为ip地址,是二进制的网络字节序,一般用inet_addr()函数完成转换
unsigned char sin_zero[8];//一般不使用
}
struct in_addr
{
uint32_t s_addr;
}
*/
memset(&my_addr,0,sizeof(struct sockaddr));
my_addr.sin_family=AF_INET;//采用IPv4网络协议
my_addr.sin_port=htons(8888);//将指定的端口号转换为网络字节序,端口号要大于1024
my_addr.sin_addr.s_addr=inet_addr("192.168.1.168");
if(bind(sfd_listen,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
{
perror("bind");
close(sfd_listen);
exit(-1);
}
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);bind的函数原型,struct sockaddr_in 只是对sa_data进行细分,大小是一样的,必须进行类型转换。
//3. 服务器使这个端口和ip处于监听状态,等待网络中客户机的链接请求
listen(sfd_listen,10);
//4.accept函数, 接受远程计算机的连接请求,建立起与客户机之间的通信连接,一旦接受请求,会返回一个新的套接口标识符,用于数据接收和发送,原先的套接口标识符则继续监听。
struct sockaddr_in clientaddr;//用于接收客户机socket信息
memset(&clientaddr,0,sizeof(struct sockaddr));
int addrlen=sizeof(struct sockaddr);
int new_sfd=accept(sfd_listen,(struct sockaddr*)&clientaddr,&addrlen);
if(new_sfd==-1)
{
perror("accept");
close(sfd_listen);
exit(-1);
}
printf("连接成功!客户机ip:%s,客户机端口号:%d\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port));
//5.recv函数,开始和客户机通信,接收客户机发送信息
char buf[1024]="";
if(recv(new_sfd,buf,sizeof(buf),0)==-1)
{
perror("recv");
close(new_sfd);
exit(-1);
}
puts(buf);
//可以用read和write函数接发数据
//6. send函数,向客户机发送数据
if(send(new_sfd,"hello",6,0)==-1)
{
perror("send");
close(new_sfd);
exit(-1);
}
//7.关闭
close(new_sfd);
close(sfd_listen);
return 0;
}
my_send.c
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char *argv[])
{
int sfd=socket(AF_INET,SOCK_STREAM,0);
if(sfd==-1)
{
perror("socket");
exit(-1);
}
struct sockaddr_in seraddr;
memset(&seraddr,0,sizeof(struct sockaddr));
seraddr.sin_family=AF_INET;
seraddr.sin_port=htons(8888);
seraddr.sin_addr.s_addr=inet_addr("192.168.1.168");
if(connect(sfd,(struct sockaddr*)&seraddr,sizeof(struct sockaddr))==-1)
{
perror("connect");
close(sfd);
exit(-1);
}
//发送和读取
char *p="hello world";
write(sfd,p,strlen(p));
char buf[1024]="";
int readn=read(sfd,buf,1023);
printf("readn:%d :%s\n",readn,buf);
close(sfd);
return 0;
}
运行:
gcc -g -o recv my_recv.c
gcc -g -o send my_send.c
主机地址是本地主机地址,也可以用不同的ip测试。