C语言模拟TCP通信-------收发数据

 简介

这篇是我学习网络编程时初次接触到的,感觉挺适合初学者,下文主要介绍了如何使用Linux模拟TCP通信,分为客户端和服务器端两大部分,外加一个总的头文件

 流程

 服务器端和客户端使用TCP的流程如下所示

 

 所用函数

 (1) socket():该函数用于创建一个套接字,同时指定协议和类型。
 (2) bind():该函数将保存在相应地址结构中的地址信息与套接字进行绑定,它主要用于服务器端,客户端创建的套接字可以不绑定定地址。
(3)listen():在服务器端程序成功建立套接字并与地址进行绑定之后通过调用listen()函数将套接字设置成监听模式(被动模式),准备接收客户端的连接请求。
(4)accept():服务器端通过调用accept()函数等待并接收客户端的连接请求。建立好 TCP 连接后,该函数会返回一个新的已连接套接字。

(5)connect():客户端通过该函数向服务器端的监听套接字发送连接请求。
(6)send()和recv():这两个函数通常在 TCP 通信过程中用于发送和接收数据,也可以用在 UDP 中。
(7)sendto()和 recvfrom():这两个函数一般在 UDP 通信过程中用于发送和接收数据。当用在 TCP 时,后面的几个与地址有关的参数不起作用,函数作用等同于 send ()和recv()。

 头文件

#ifndef _NET_H
#define _NET_H

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

#endif

 客户端

步骤

     创建发送端Socket对象(创建连接)
     获取输出流对象
     发送数据
     释放资源

#include "net.h"

int tcp_connect(const char *ip,int port);
int tcp_connect(const char *ip,int port)
{
	//1,创建socket对象,流式套接字
	//参数1 地址族 AF_INET表示IPV4协议
	//参数2 套接字类型 SOCK_STREAM表示流式套接字 适用于TCP协议
	//参数3 一般为0
	int tcp_socket=socket(AF_INET,SOCK_STREAM,0);
	if(tcp_socket<0)
	{
		perror("socket error\n");
		return -1;
	}
	printf("socket ok\n");
	//2.设置对方的IP地址和端口号
	//2.1定义一个结构体,赋值
	struct sockaddr_in server;

	server.sin_family=AF_INET;//IPV4
	server.sin_port=htons(port);//端口号
	server.sin_addr.s_addr=inet_addr(ip);//转换成网络字节序
	//3,请求连接
	//参数1 socket 对象
	//参数2 struct socket *    实际struct socksddr_in
	if(connect(tcp_socket,(struct sockaddr *)&server,sizeof(server))<0)
	{
		perror("connect error");
		return -1;
	}
	printf("connect ok\n");
	return tcp_socket;
}

int main(int argc, const char *argv[])
{
	//1,创建socket对象,流氏套接字
	//2.设置对方的IP地址和端口号
	//3,请求连接
	//4.发送接受消息
	//5.关闭socket对象
	if(argc<3)
	{
		printf("输入错误,请重新输入\n");
		exit(1);
	}

	int tcp_socket=tcp_connect(argv[1],atoi(argv[2]));
	char buf[20]={'\0'};
	fgets(buf,sizeof(buf),stdin);
	send(tcp_socket,buf,strlen(buf),0);
	//5关闭socket对象
	close(tcp_socket);
	return 0;
}

 服务器端

步骤:
         创建接收端Socket对象
         监听
         获取输入流对象
         获取数据
         输出数据
         释放资源

#include "net.h"

int tcp_server(const char *ip,int port);
int tcp_server(const char *ip,int port)
{
	//1,创建socket对象,流式套接字
	//参数1 地址族 AF_INET表示IPV4协议
	//参数2 套接字类型 SOCK_STREAM表示流式套接字 适用于TCP协议
	//参数3 一般为0
	int tcp_socket=socket(AF_INET,SOCK_STREAM,0);
	if(tcp_socket<0)
	{
		perror("socket error\n");
		return -1;
	}
	//2.设置对方的IP地址和端口号
	//2.1定义一个结构体,赋值
	struct sockaddr_in server;
	memset(&server,'\0',sizeof(server));
	server.sin_family=AF_INET;//IPV4
	server.sin_port=htons(port);//端口号
	server.sin_addr.s_addr=inet_addr(ip);//转换成网络字节序

	//3,请求连接
	//参数1 socket 对象
	//参数2 struct socket *    实际struct socksddr_in
	if(bind(tcp_socket,(struct sockaddr *)&server,sizeof(server))<0)
	{
		perror("bind error\n");
		return -1;
	}
	printf("bind ok\n");
	if(listen(tcp_socket,5)<0)
	{
		perror("listen error");
	}
	printf("listen ok\n");
	return tcp_socket;
}

int main(int argc, const char *argv[])
{
	//1.socket对象,流氏套接字
	//2.设置对方的IP地址和端口号
	//3.请求连接
	//4.发送接受消息
	//5.关闭socket对象
	if(argc!=3)
	{
		printf("输入错误,请重新输入\n");
		exit(1);
	}

	int tcp_socket=tcp_server(argv[1],atoi(argv[2]));
	int newfd=0;
	struct sockaddr_in client;
	int len=sizeof(client);
	newfd=accept(tcp_socket,(struct sockaddr *)&client,&len);
	if(newfd<0)
	{
		perror("accept error");
		return -1;
	}
	printf("accept ok\n");
	printf("client ip:%s port:%d\n",inet_ntoa(client.sin_addr),ntohs(client.sin_port));

	char buf[20]={'\0'};
	recv(newfd,buf,sizeof(buf),0);
	printf("%s\n",buf);
	//5.关闭socket对象
	close(tcp_socket);
	return 0;
}

小结

以上就是小编边学边码出来的,如有不对,请多指正~~

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值