Linux单用户CS模型TCP通讯完全注释手册
Linux单用户CS模型TCP通讯完全注释手册
server
描述
- 实现一个简单的Linux单用户CS通讯,客户端发送一串字符串,服务器将其转换为大写后返回。
server 代码
```
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#define SERV_PORT 6666
int main(int argc,char *argv[])
{
int sfd, cfd;//定义服务器的文件描述符std, 定义客户端的文件描述符cfd, cfd用来与客户端通讯,sfd用来接受客户端接入请求.
int len, i;//定义读取客户端数据长度返回值len, 定义操作字符时的循环变量i
char buf[BUFSIZ], clie_IP[BUFSIZ];//定义buf接收字符串, 定义clie_IP接收套接字中客户端IP
struct sockaddr_in serv_addr, clie_addr;//定义服务器结构体,客户端结构体
socklen_t clie_addr_len;//定义客户端套接字长度
sfd = socket(AF_INET, SOCK_STREAM, 0);//创建一个服务器套接字,返回文件描述符
bzero(&serv_addr, sizeof(serv_addr));//给结构体清零
serv_addr.sin_family = AF_INET;//设置结构体协议族为IPv4
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);//设置结构体IP为所有有效网卡的IP,这里需要用htonl将INADDR_ANY转为网络字节序.
serv_addr.sin_port = htons(SERV_PORT);//设置端口,这里htons为转为网络字节序
bind(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));//设置文件描述符与结构体绑定(ip, port, 网卡等).
listen(sfd, 2);//参数2为半连接及已连接但在等待accept分配文件描述符的连接数的总和,Linux默认最大128(该值可修改)
printf("Wait for client connect ...\n");
while(1)
{
clie_addr_len= sizeof(clie_addr);//初始化客户端结构体长度
cfd = accept(sfd, (struct sockaddr *)&clie_addr, &clie_addr_len);//给客户端连接分配文件描述符,并保存客户端IP端口等信息到clie_addr结构体中
printf("cfd = ----------%d\n", cfd);
printf("client IP : %s, port : %d\n", /*打印客户端IP,端口号,这里从in_addr_t类型转换到字符串类型,需要用inet_ntop函数*/
inet_ntop(AF_INET, &clie_addr.sin_addr.s_addr, clie_IP, sizeof(clie_IP)),
ntohs(clie_addr.sin_port)/*将端口号转换为本地字节序*/
);
do //循环处理客户端请求
{
len = read(cfd, buf, sizeof(buf));
write(STDOUT_FILENO, buf, len);
for(i = 0; i< len; ++i)
{
buf[i] = toupper(buf[i]);
}
write(cfd, buf, len);
}while(len);
close(cfd);//通讯结束,关闭客户端文件描述符
}
close(sfd);//通讯结束,关闭服务器文件描述符
return 0;
}
```
client代码实现
```
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define SERV_IP "127.0.0.1"
#define SERV_PORT 6666
int main(int argc,char *argv[])
{
int sfd, len;//定义与server通讯的文件描述符sfd, 定义读取到的数据(server发的)的长度len
struct sockaddr_in serv_addr;//定义与server通讯的套接字serv_addr
char buf[BUFSIZ];//定义buf接收server发送的数据
sfd = socket(AF_INET, SOCK_STREAM, 0);//初始化文件描述符sfd,协议族为AF_INET(即IPv4), 应用协议为SOCK_STREAM(即TCP协议),第三个参数默认0
bzero(&serv_addr, sizeof(serv_addr));//将套接字清零
serv_addr.sin_family = AF_INET;//设置套接字协议族为IPv4
inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);//将IP地址转换为in_addr_t类型存入
serv_addr.sin_port = htons(SERV_PORT);//将端口转为网络字节序存入
connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));//按照套接字里服务器信息连接服务器,并设置sfd文件描述符用来通讯
while(1)//与服务器通讯过程,本例为给server发送一行数据,然后打印server发回的数据.
{
fgets(buf, sizeof(buf), stdin);
int ret = write(sfd, buf, strlen(buf));
printf("write ret = %d\n", ret);
len = read(sfd, buf, sizeof(buf));
printf("read len = %d\n", len);
write(STDOUT_FILENO, buf, len);
}
close(sfd);//关闭文件描述符
return 0;
}
```
运行效果
- 客户端输入:hello,world
- 服务端转换为大写后返回,客户端收到服务器发回的数据后进行打印:HELLO,WORLD
如图

存在问题
- 仅作学习建立TCP连接使用,不支持多用户,未进行错误处理。
Linux单用户CS模型TCP通讯完全注释手册的更多相关文章
- linux单用户模式
linux单用户模式 2014年11月11日 17:18 在grub上相应要启动的内核上按“e”. 进入下一界面,继续按“e”. 在进入文本界面后,输入“single”回车. 进入grub界面后,按“ ...
- linux单用户模式修改密码
Linux使用版本: Centos 7 救援模式: 1,在虚拟机设置里查看光驱是否开启启动,要保证设置状态里的两个选项都已选择. 2,先将Centos系统关机,然后在VMware左侧选中这台虚拟机并右 ...
- Linux单用户模式(修改密码、运行级别)方法详解
很多新手当面对"忘记 root 账户密码导致无法登陆系统"这个问题时,直接选择重新系统.其实大可不必,我只需要进入 emergency mode(单用户模式)更新 root 账户的 ...
- Linux 单用户模式的使用
在进入系统启动菜单时,选择kernel,输入"e"后进入,在kernel开头的启动项后输入(空格) /single或者 / 1,然后输入"b"重新启动机器,此时 ...
- 进入Linux单用户模式
1. 在启动系统出现如下画面时按Enter键进入系统设置页面: 2. 系统设置页面: 3. 按下e键进入: 4. 选择第二项,按e键进入 5. ...
- linux单用户模式修改密码与系统启动级别
目录 一:系统启动级别 二:单用户模式修改密码 一:系统启动级别 系统启动级别: 0 关机 1 单用户模式(无法通过xshell方式使用)(虚拟机操作)(系统云服务商后台) 2 多用户无网络模式 3 ...
- Linux系统网络编程中TCP通讯socket--send导致进程被关闭
https://blog.csdn.net/dsanmux/article/details/52083403 https://blog.csdn.net/u011425939/article/deta ...
- linux 单用户密码修改
1.启动系统,并在GRUB2启动屏显时,按下e键进入编辑模式. 2.在linux16/inux/linuxef所在参数行ro更改为init=/sysroot/bin/sh 3.按Crl+x启动到she ...
- Linux进入单用户模式
有时候配置linux的过程中,因为一些误操作导致系统初始化时堵塞或挂起而无法进入系统,原因往往是因为配置文件设置错误,部分文件被误删之类.遇到这种情况一般新手的做法就是重装(虚拟机不装白不装),但在实 ...
随机推荐
- 关于Angular中时间戳的计算
前言 使用的是Moment.js 插件,插件的安装详情请参考官方网址(https://momentjs.com/) 正文 步骤一:引用import * as moment from 'moment'; ...
- Python初学者第十七天 函数(1)
17day 函数 1.函数定义: 函数 是指将一组语句的集合通过一个名字(函数名)封装起来,想要执行这个函数,只需调用其函数名即可 2.函数的特性: a 减少重复代码 b 使程序变得可扩展 c 使程序 ...
- CSS边框长度控制
以前需要边框长度比容器小一些时,我用div嵌套.后来发现伪类在实现这个效果时很方便,只需要一个div就够了,另外调整padding和margin都不会很麻烦. <div class=" ...
- 软工团队 - 预则立&&他山之石
软工团队 - 预则立&&他山之石 团队任务计划 时间 人员 任务 10.23-10.29 张昭锡 初拟Android代码规范 李永盛 初拟PHP代码规范 刘晨瑶 初拟Git代码规范 刘 ...
- Metaspliot进行漏洞扫描
Metaspliot进行漏洞扫描 Metasploit框架是Metasploit项目中最著名的创作,是一个软件开发.测试和利用漏洞的平台.它可以用来创建安全测试工具开发的模块,也可利用模块作为一个渗透 ...
- Python正则表达式(总)
转载请标明出处: http://www.cnblogs.com/why168888/p/6445044.html 本文出自:[Edwin博客园] Python正则表达式(总) search(patte ...
- Mac原生Terminal快速登录ssh
1. 创建rsa key 在终端中输入以下命令: ssh-keygen -t rsa 完成之后可以在~/.ssh目录下找到公钥和私钥 如果你与我一样有使用gitlab,那么这个秘钥应该已经存在 ...
- Android Studio 动态调试 apk 反编译出的 smali 代码
在信安大赛的准备过程中,主要通过 Android Studio 动态调试 apk 反编译出来的 smali 代码的方式来对我们分析的执行流程进行验证.该技巧的主要流程在此记录.以下过程使用 Andro ...
- vue项目出现的错误汇总
报错一: expected "indent", got "!" 通过vue-cli创建的项目,不需要在webpack.base.conf.js中再手动配置关于c ...
- BZOJ 1562 变换序列 二分图匹配+字典序
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1562 题目大意: 思路: 逆序匹配,加边匹配的时候保持字典序小的先加入. 具体证明:h ...