基于tcp的服务器端和客户端简单版

一、基于tcp的服务器端和客户端的基本模型

 

二、基本的代码

TcpServer.c

/*
 ============================================================================
 Name        : TcpServer.c
 Author      : nicholas
 Version     :
 Copyright   : 韦轩
 Description : TCP server
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include<sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
/**
 *函数的调用顺序
 *1.socket函数
 *2.bind函数
 *3.listen函数
 *4.accept函数
 *5.read/write函数
 *6.close函数
 */
int main(int argc,char * argv[]){

	//第一步:创建server socket
	/**
	 * 1.socket函数 头文件 #include<sys/socket.h>
	 * 函数原型 socket(int domain,int type,int protocol) ----成功返回文件描述符,失败返回-1
	 * domain:套接字中的协议族(protocol family信息) pf_inet  ---ipv4 (一般是pf_inet)
	 * type:套接字的传输类型  面向连接的 sock_stream (TCP) 面向消息的 sock_dgram(udp)
	 * protocol:计算机通信使用的协议 一般的参数是0,如果同一协议族中存在多个,则需要指定协议信息
	 * tcp 直接指定为ipproto_tcp  udp 直接指定为 ipproto_udp
	 */
	int server_socket = socket(PF_INET,SOCK_STREAM,0);

	if(server_socket==-1)
		puts("socket error...");
	//初始化地址信息
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;

	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(atoi(argv[1]));

	/**第二步:2.bind函数
	 * 函数原型 int bind(int sockfd,struct sockaddr* myaddr,socklen_t addrlen)
	 * 成功返回0 ,失败返回-1
	 *sockfd ----要分配地址信息的(ip地址和端口号)的套接字文件描述符
	 *myaddr存有地址信息的结构体变量的地址值
	 *第二个结构体的长度
	 */
	if(bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
		puts("bind() error ....");

	/**第三步:3.listen函数  函数原型:int listen(int sock,int backlog)
	 * 成功返回0,失败返回-1
	 * sock:希望进入等待连接请求状态的套接字文件描述符,传递的描述符套接字参数成为服务器端套接字(监听套接字)
	 * backlog 连接请求等待队列的长度,若为5,则表示最多使5个连接请求进入队列
	 */
	if(listen(server_socket,5)==-1)
		puts("Listen() error ...");

	/**第四步:accept
	 * 函数原型:int accept(int sock,struct sockaddr* addr,socklen_t * addrlen)
	 * 成功返回创建的套接字描述符,失败返回-1
	 * sock :服务器套接字描述符
	 * addr :保存发起连接请求的客户端地址信息的变量地址,函数调用后,向传来的地址变量参数填充客户端地址信息
	 * addrlen 第二个参数addr结构体的长度,但是存放的是该长度的地址,函数调用后,被填入客户端地址长度
	 */
	ssize_t clint_addr_size = sizeof(client_addr);
	int client_socket  = accept(server_socket,(struct sockaddr*)&client_addr,&clint_addr_size);
	if(client_socket==-1)
		puts("accept() error ...");

	/** 第五步:write()函数
	 * write函数原型:ssize_t write(int fd,const void* buf,size_t nbytes)
	 * 成功时返回写入的字节数,失败时,返回-1
	 * fd 显示数据传输对象的文件描述符
	 * buf 保存要传输数据的缓冲地址值
	 * nbytes 要传输的字节数
	 */
	char message[] = "Hello,now is 2015-04-10 09:57:45";
	write(client_socket,message,sizeof(message));

	/**第六步:close
	 *
	 */

	close(client_socket);
	close(server_socket);
	return EXIT_SUCCESS;
}


TcpClient.c

/*
 ============================================================================
 Name        : TcpClient.c
 Author      : nicholas
 Version     :
 Copyright   : 韦轩
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

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

/**函数调用顺序
 * 1.socket 创建客户端socket
 * 2.connect请求连接
 * 3.read/write数据交换
 * 4.close
 */
int main(int argc, char **argv) {

	int client_socket = socket(PF_INET,SOCK_STREAM,0);
	if(client_socket==-1)
		puts("socket() error..");

	/**connect 函数
	 *int connect(int sock,struct sockaddr* servaddr,socklen_t addrlen)
	 * 成功返回0,失败返回-1
	 * sock 客户端套接字描述符
	 * servaddr 保存目标服务器端地址信息的变量地址值
	 * addrlen 以字节为单位传递已传递给第二个结构体参数servaddr的地址变量长度
	 */

	struct sockaddr_in server_addr;
	memset(&server_addr,0,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);
	server_addr.sin_port = htons(atoi(argv[2]));

	if(connect(client_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))==-1)
		puts("connect() error...");

	char meaasge[100];
	ssize_t len = read(client_socket,meaasge,sizeof(meaasge)-1);

	if(len==-1)
		puts("Read() Error ...");

	printf("Message from server is %s , and the length is %d\n",meaasge,len);

	close(client_socket);

	return 0;
}


三、运行结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值