1.TCP介绍

传输控制协议
特点:
出错重穿,每次发送数据对方都会回ACK
安全可靠

2.服务器客户端TCP通信模型

tcpjava客户端 tcp客户端流程_通信


客户端:打电话模型(建立连接,使用连接,关闭连接)

创建套接字 (客户电话)–连接服务器(连接,拨号)–收发数据(读写对socket文件操作)(说话交流)–关闭(挂电话)

相关函数说明

1. socket函数 – 语意:创建套接字

#include <sys/types.h> / See NOTES /
#include <sys/socket.h>
int socket(int domain, int type, int protocol);

具体参数

domain:(socket协议选择)

AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
AF_INET6 与上面类似,不过是来用IPv6的地址
AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用

type:(套接字类型)

SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
SOCK_SEQPACKET该协议是双线路的、可靠的连接,发送固定长度的数据包进行传输。必须把这个包完整的接受才能进行读取。
SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
SOCK_RDM 这个类型是很少使用的,在大部分的操作系统上没有实现,它是提供给数据链路层使用,不保证数据包的顺序

protocol:
传0 表示使用默认协议。

返回值:
成功:返回指向新创建的socket的文件描述符sockdf,供给后面用
失败:返回-1,设置errno

描述

socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符,应用程序可以像读写文件一样用read/write在网络上收发数据,如果socket()调用出错则返回-1。对于IPv4,domain参数指定为AF_INET。对于TCP协议,type参数指定为SOCK_STREAM,表示面向流的传输协议。如果是UDP协议,则type参数指定为SOCK_DGRAM,表示面向数据报的传输协议。protocol参数的介绍从略,指定为0即可。

2.connect函数 – 语意:连接服务器

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
sockdf:
socket文件描述符,刚才创建的描述符
addr:
传入参数,ipv4/ipv6通用套接字结构体地址(指定服务器端地址信息,含IP地址和端口号)类型不对要强转,转为通用的结构体地址
addrlen:
传入参数,传入sizeof(addr)大小,传入套接字结构体长度
返回值:
成功返回0,失败返回-1,设置errno
客户端需要调用connect()连接服务器,connect和bind的参数形式一致,区别在于bind的参数是自己的地址,而connect的参数是对方的地址。connect()成功返回0,出错返回-1

过程代码实例(重点)

#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <sys/socket.h>

int main(int argc, char *argv[])
{
	//创建套接字
	int sock_fd;
	sock_fd = socket(AF_INET,SOCK_STREAM,0);
	//创建ipv4套接字结构体--把服务器三要素赋给客户端
	struct sockaddr_in addr;
	addr.sin_family = AF_INET;//设置ipv4地址格式
	addr.sin_port = htons(8080);//主机字节序转网络字节序
	inet_pton(AF_INET,"192.168.21.29",&addr.sin_addr.s_addr);//将点分十进制串转换成网络大端
	//连接服务器
	connect(sock_fd,(struct sockaddr *)&addr,sizeof(addr));//connect要转换成通用套接字结构体类型
	
	char buf[1024]="";
	while(1)
	{
		int n = read(STDIN_FILENO,buf,sizeof(buf));
		write(sock_fd,buf,n);//写数据
		n = read(sock_fd,buf,sizeof(buf));//读数据
		write(STDOUT_FILENO,buf,n);
		printf("\n");
	
	}1

	
	
//关闭套接字
	close(sock_fd);

	return 0;
}