您的位置:首页 > 理论基础 > 计算机网络

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

2015-04-10 14:22 369 查看
一、基于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;
}


三、运行结果



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: