简介
这篇是我学习网络编程时初次接触到的,感觉挺适合初学者,下文主要介绍了如何使用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;
}
小结
以上就是小编边学边码出来的,如有不对,请多指正~~
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)