TCP 仅创建服务器和客户端

cs架构 服务器

1.创建套接字 socket
2.绑定套接字 bind
3.监听套接字listen
4.被动等待连接 accept
5.send/recv read/write(linux)
6.关闭套接字 close

客户端

1.创建套接字 socket
2.绑定 bind(可省略)
3.主动连接 connect
4.send/recv read/write(linux)
5.关闭套接字 close
//1.socket创建套接字
int socket(int domain, int type, int protocol);
/*返回值  成功返回文件描述符,失败返回-1

 参数:domain 地址族 ipv4 AF_INET
       type  类型 SOCK_STREAM (TCP)
       protocpl 协议 一般默认0

*/
eg:
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(ERROR == sockfd)
	{
		perror("socket");
		return ERROR;
	}


//2.bind绑定套接字
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*
	返回值:成功返回0 失败返回-1

	参数:sockfd  文件描述符
	     addr 装有信息的结构体
	     addrlen 结构体的长度
*/
/*
	网络字节序:htons() 把短整型的数据转换位网络字节序
	           ntohs() 把网络字节序转成短整型的数据
	           inet_addr()把字符串类型的ip地址转换位网络字节序  “192.168.3.4”
	           char *inet_ntoa(struct in_addr in);

	struct sockaddr_in {
               sa_family_t    sin_family;  address family: AF_INET 
               in_port_t      sin_port;    port in network byte order 
               struct in_addr sin_addr;   internet address 
           };

         Internet address. 
           struct in_addr {
               uint32_t       s_addr;      address in network byte order 
           };
*/
eg:
	struct sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(6666);
	addr.sin_addr.s_addr = inet_addr(0.0.0.0);

	if(ERROR == bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)))
	{
		perror("bind");
		return ERROR;
	}

3./*设置监听队列*/
int listen(int sockfd, int backlog);
/*
	返回值 成功返回0, 失败返回-1

	参数:sockfd 文件描述符
	      backlog 监听队列的大小 一般3或者4
*/
eg:
	if(ERROR == listen(sockfd, 3))
	{
		perror("listen");
		return -1;
	}

/*被动等待连接*/
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/*
	返回值:成功返回客户端的文件描述符,失败返回-1

	参数:sockfd  文件描述符
	     addr    接收客户端信息的内存首地址
	     addrlen 空间的大小(不能用sizeof,需要先计算出来赋值给一个变量,把变量地址传递进来)
*/
eg:
	struct sockaddr_in c_addr;
	memset(&c_addr, 0, sizeof(c_addr));
	socklen_t c_addrlen = sizeof(c_addr);
	int connfd;
flag:
	if(ERROR == (connfd = accept(sockfd, (struct sockaddr*)&c_addr, &c_addrlen)))   //阻塞等待客户端连接
	{
		perror("listen");
		exit(ERROR);
	}
	
	printf("connfd is %d\n", connfd);
	printf("port is %d\n", ntohs(c_addr.sin_port));
	printf("ip is %s\n", inet_ntoa(c_addr.sin_addr));

/*发送函数*/
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
/*
	返回值: 成功返回发送数据的字节数,失败-1

	参数:sockfd 文件描述符
	      buf 发送内容首地址
	      len 内容长度

	      flags 0和write一样

*/
eg:
		char buf[20] = {0};
		ssize_t ret;
		ret = recv(connfd, buf, sizeof(buf), 0);
		if(ERROR == ret)
		{
			perror("recv");
			exit(ERROR);
		}
		if(ZERO == ret)
		{
			goto flag;
		}
		printf("recv number=%ld\n", ret);
		printf("data is %s\n", buf);

/*接收函数(阻塞)*/
ssize_t recv(int sockfd, const void *buf, size_t len, int flags);
/*
	返回值: 成功返回读取数据的字节数,失败-1,客户端退出返回0

	参数:sockfd 文件描述符
	      buf 接收内容首地址
	      len 内容长度

	      flags 0和read一样

*/
/*客户端主动连接服务器*/
int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
/*
	返回值 成功返回0, 失败返回-1
	参数:sockfd  文件描述符
	      addr  需要连接的服务器的地址信息
	      addrlen 结构体长度
*/
		fgets(buf, sizeof(buf), stdin);
		ret = send(connfd, buf, sizeof(buf), ZERO);
		if(ERROR == ret)
		{
			perror("send");
			exit(ERROR);
		}
		printf("send number=%ld\n", ret);

全部评论

相关推荐

M_bao:换个排版吧哥们,看着费劲
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务