简单的TCP通信实例

目的:基于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测试。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值