基于TCP的客户端和服务器端的代码设计
实验平台
linux
实验内容
编写TCP服务器和客户端程序,程序运行时服务器等待客户端连接。一旦连接成功,服务器显示客户端的IP地址和端口号,并向客户端发送字符串
实验原理
TCP是面向连接的通信,其主要实现过程如下:

我们将服务器代码分为两部分。
1. init_tcp_server() tcp服务器的初始化
2. main() 实现读写数据
这样做的好处是main函数不必写的特别冗长,利于维护。从框架上来说,服务器的初始化也与读、写无关。
tcp服务器的初始化----init_tcp_server()
1. 创建socket
sockfd = socket(AF_INET, SOCK_STREAM, ); //AF_INT:ipv4, SOCK_STREAM:tcp协议
2. 设置socket 当然这一步可以省略
int32_t opt = ;
ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
详细说明:
3. 绑定(bind函数)
将socket和地址(包括ip,port)绑定。需要定义一个结构体地址,以便于将port的主机字节序转化成网络字节序
struct sockaddr_in serveraddr; //地址结构体
bind函数
bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))
4. listen监听,将接收到的客户端放入队列
listen(sockfd,) //第二个参数是队列长度
5. 调用accept函数,从队列获取请求,返回socket描述符,如果没有请求(没有客户端连接),将会阻塞,直到获取请求
int fd=accept(sockfd, (struct sockaddr*)&clientaddr, &clientaddr_len);
至此服务器初始化完成,返回成功连接的套接字fd。
服务器端代码如下:tcpserver.c
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h> #define PORT 1234
#define BACKLOG 10
#define BUFFER_SIZE 100 /**
* @brief 初始化tcp服务器
* @param[in] listenfd 监听套接字
* @return -1 - 失败, socket 文件句柄 - 成功
*/
int32_t init_tcp_server(int32_t listenfd)
{
struct sockaddr_in server;
struct sockaddr_in client; int32_t connectfd = ;
int32_t addrlen;
int32_t ret = ;
addrlen = sizeof(client); /**< 创建一个tcp套接字 */
listenfd = socket(AF_INET, SOCK_STREAM, );
if (listenfd == -)
{
perror("create socket failed!\n");
exit();
} /**< 设置一个tcp套接字 */
int32_t opt = ;
ret = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if (ret < )
{
perror("set socket failed!\n");
exit();
} /**< 设置服务器监听所有的IP地址 */
bzero(&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(PORT); /**< 主机字节序转化成网络字节序 */
server.sin_addr.s_addr = htonl(INADDR_ANY); /**< 与服务器进行绑定 */
if (bind(listenfd, (struct sockaddr *)&server, sizeof(server)) == -)
{
perror("bind error");
exit();
} /**< 监听 */
if (listen(listenfd, BACKLOG) == -)
{
perror("listen error");
exit();
} /**< 等待客户端连接,如果没有,一直阻塞 */
if ((connectfd = accept(listenfd, (struct sockaddr *)&client, &addrlen)) == -)
{
perror("accept error");
close(listenfd);
close(connectfd);
exit();
}
printf("You got a connection from client's ip is %s, port is %d\n", inet_ntoa(client.sin_addr), htons(client.sin_port)); return connectfd;
} int main()
{
int32_t listenfd = ;
int32_t connectfd = ;
char buf[BUFFER_SIZE] = "Welcome to my server"; connectfd = init_tcp_server(listenfd); send(connectfd, buf, BUFFER_SIZE, ); /**< 发送信息到客户端 */
close(connectfd);
close(listenfd);
}
客户端
同样,将客户端代码分成两部分:
1. init_tcp_client() tcp客户端的初始化
2. main() 实现读写数据
客户端的初始化较为简单,如上图,只要实现socket和connect函数即可。但是我们希望可以手动输入客户端连接的IP地址,便于以后扩展,因此需要给客户端初始化传入一个参数。例如,输入:
./tcpclient 127.0.0.1
客户端代码如下:tcpclient.c
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h> #define PORT 1234
#define BUFFER_SIZE 100 int32_t init_tcp_client(char *ipaddr)
{
int sockfd = ;
struct sockaddr_in server; if ((sockfd = socket(AF_INET, SOCK_STREAM, )) == -)
{
perror("create socket failed!\n");
exit();
} bzero(&server, sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
inet_pton(AF_INET, ipaddr, &server.sin_addr.s_addr); /**< 点分十进制转换成二进制的网络字节序 */ if (connect(sockfd, (struct sockaddr *)&server, sizeof(server)) == -)
{
perror("connect error");
exit();
} return sockfd;
} int32_t main(int argc, char*argv[])
{
int32_t sockfd, num;
char buf[BUFFER_SIZE];
if (argc != )
{
printf("Usage:%s <IP Address>\n",argv[]);
exit();
}
sockfd = init_tcp_client(argv[]); if ((num = recv(sockfd, buf, BUFFER_SIZE, )) == -)
{
perror("recv error");
exit();
} buf[num - ] = '\0';
printf("Server Message: %s\n", buf);
close(sockfd); return ;
}
Makefile文件如下:
all:server client server:tcpserver.c
gcc tcpserver.c -o server client:tcpclient.c
gcc tcpclient.c -o client clean:
rm -rf server client
实验结果如下:


基于TCP的客户端和服务器端的代码设计的更多相关文章
- 基于UDP的客户端和服务器端的代码设计
实验平台 linux 实验内容 编写UDP服务器和客户端程序,客户端发送消息,服务器接收消息,并打印客户端的IP地址和端口号. 实验原理 UDP是无需连接的通信,其主要实现过程如下: 同样,我们可以按 ...
- 基于TCP的客户端、服务器端socket编程
一.实验目的 理解tcp传输客户端服务器端通信流程 二.实验平台 MAC OS 三.实验内容 编写TCP服务器套接字程序,程序运行时服务器等待客户的连接,一旦连接成功,则显示客户的IP地址.端口号,并 ...
- UDP广播的客户端和服务器端的代码设计
实验环境 linux 注意: 使用UDP广播,是客户端发送广播消息,服务器端接收消息.实际上是客户端探测局域网中可用服务器的一种手段.客户端发送,服务器端接收,千万不能弄混淆!!! 为了避免混淆,本文 ...
- 使用CXF开发WebService程序的总结(四):基于bean的客户端和服务端代码的编写
1. 在原服务端项目 ws_server中添加两个bean 1.1 添加两个类 User 和 Clazz package com.lonely.pojo; public class User { ...
- 实验09——java基于TCP实现客户端与服务端通信
TCP通信 需要先创建连接 - 并且在创建连接的过程中 需要经过三次握手 底层通过 流 发送数据 数据没有大小限制 可靠的传输机制 - 丢包重发 包的顺序的 ...
- C/S模型:TCP,UDP构建客户端和服务器端(BIO实现
Java中提供了socket编程来构建客户端和服务器端 TCP构建服务器端的步骤:(1)bind:绑定端口号(2)listen:监听客户端的连接请求(3)accept:返回和客户端连接的实例(4)re ...
- 【TCP/IP网络编程】:04基于TCP的服务器端/客户端
摘要:结合前面所讲述的知识,本篇文章主要介绍了简单服务器端和客户端实现的框架流程及相关函数接口. 理解TCP和UDP 根据数据传输方式的不同,基于网络协议的套接字一般分为TCP套接字和UDP套接字(本 ...
- C/C++网络编程5——实现基于TCP的服务器端/客户端2
三次握手过程详解: 1:客户端的协议栈向服务器端发送SYN包,并告诉服务器端当前放送序号为j,客户端进入SYNC_SEND状态. 2:服务器端的协议栈收到这个包以后,和客户端进行ACK应答,应答值为j ...
- 基于TCP的安卓客户端开发
一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客户 ...
随机推荐
- 21.1 Math(数学运算)方法使用 、工具类
package day21_static.meathDemo; //Math: 包含一些基本的数学运算方法 //从api中搜Math,它都用的static修饰. public class MethDe ...
- Python Requests-学习笔记(10)-会话对象
会话对象让你能够跨请求保持某些参数.它也会在同一个Session实例发出的所有请求之间保持cookies. 会话对象具有主要的Requests API的所有方法. 我们来跨请求保持一些cookies: ...
- 超详细Go语言源码目录说明
开源项目「go home」聚焦Go语言技术栈与面试题,以协助Gopher登上更大的舞台,欢迎go home~ 导读 学习Go语言源码的第一步就是了解先了解它的目录结构,你对它的源码目录了解多少呢?今天 ...
- Pod容器共享Volume
同一个Pod中的多个容器能够共享Pod级别的存储卷Volume.Volume可以被定义为各种类型,多个容器各自进行挂载操作,将一个Volume挂载为容器内部需要的目录,如图 在下面的例子中,在Pod内 ...
- tomcat通过tomcat 安装根目录下的conf-Catalina-localhost目录发布项目详解
tomcat通过conf-Catalina-localhost目录发布项目详解 Tomcat发布项目的方式大致有三种,但小菜认为通过在tomcat的conf/Catalina/localhost目 ...
- Python——flask漏洞探究
python的用途是真的多,就连网站也能做,这个有点像Java的Servlet flask基础 hello world 我们先从基础的开始,在网页上打出hello world,python代码如下: ...
- Docker-None & Host 网络
本节介绍None&Host网络. 1.前言 点击此处回到docker系列文章目录 前面我们介绍了bridge network,本小节继续介绍none和host.这两个比较简单,也不太常用.安装 ...
- 数据类型、运算符、Scanner的使用
一.常见的基本数据类型 数值型 byte(最小,2字节) short(4字节) int (默认 8字节) long(16字节) 浮点型 f ...
- 详解 DatagramSocket类
(请观看本人博文 -- <详解 网络编程>) DatagramSocket 概述: 这类代表一个发送和接收数据包的插座. 该类是遵循 UDP协议 实现的一个Socket类. 数据报套接字发 ...
- SringMVC入门程序
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架 1.Spring优点 轻量级,简单易学 高效 , 基于请求响应的MVC框架 与Spring兼 ...