linux面向连接的套接字编程
更新时间:2023-06-03 05:47:01 阅读量: 实用文档 文档下载
1.本实验完成面向链接的套接字,并且进行通信。
2.面向链接的套接字的工作流程;
3.服务器先用socket函数来建立一个套接字,用这个套接字完成通信的监听。
4.用bind函数来绑定一个端口号和IP地址。因为本地计算机可能有多个网址和IP,每一个IP
和端口有多个端口。需要指定一个IP和端口进行监听。
5.服务器调用listen函数,使服务器的这个端口和IP处于监听状态,等待客户机的连接。
6.客户机用socket函数建立一个套接字,设定远程IP和端口。
7.客户机调用connect函数连接远程计算机指定的端口。
8.服务器用accept函数来接受远程计算机的连接,建立起与客户机之间的通信。
9.建立连接以后,客户机用write函数向socket中写入数据。也可以用read函数读取服务器
发送来的数据。
10.服务器用read函数读取客户机发送来的数据,也可以用write函数来发送数据。
11.完成通信以后,用close函数关闭socket连接。
12.客户机与服务器建立面向连接的套接字进行通信。
实验结果截图:
详细步骤:
1.绑定描述:
函数bind可以将一个端口绑定到一个已经建立的socket上,这个函数的使用方法如下所示。 int bind(int sockfd,struct sockaddr * my_addr,int addrlen);
参数列表中,sockfd是已经建立的socket编号。sockaddr是一个指向sockaddr结构体类型的
指针。sockaddr的定义方法如下所示。
struct sockaddr
{
unsigned short int sa_family;
char sa_data[14];
};
2.监听函数:
listen函数用于实现监听等待功能。这个函数的使用方法如下所示。
int listen(int s,int backlog);
在参数列表中,s是已经建立的socket。backlog是能同时处理的最大连接请求。如
果超过这个数目,客户端将会接收到ECONNREFUSED拒绝连接的错误。
3.接受链接请求函数:
接受连接请求的函数是accept,这个函数的使用方法如下所示。
int accept(int s,struct sockaddr * addr,int * addrlen);
在参数列表中,s是处于监听状态的socket。addr是一个sockaddr结构体类型的指针,系统
会把远程主机的这些信息保存到这个结构体指针上。addrlen是sockaddr的内存长度,可以
用sizeof函数来取得。
4.请求链接函数:
connect函数可以完成请求连接的功能,这个函数的使用方法如下所示。
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
在参数列表中,sockfd是已经建立的socket。serv_addr是一个结构体指针,指向一个
sockaddr结构体。这个结构体存储着远程服务器的IP与端口信息。addrlen是sockaddr结构
体的内存长度,可以用sizeof函数来获取。
5.接受发来的数据函数:
函数recv可以接收远程主机发送来的数据,并把这些数据保存到一个数组中。该函数的使用
方法如下所示。
int recv(int s,void *buf,int len,unsigned int flags);
在参数列表中,s是已经建立的socket。buf是一个指针,指向一个数组。接收到的数据会保
存到这个数组上。len是数组的长度,可以用sizeof函数来取得。
6.信息发送函数send:
用connect函数连接到远程计算机以后,可以用send函数将信息发送到对方的计算机。这个
函数的使用方法如下所示。
int send(int s,const void * msg,int len,unsigned int flags);
在参数列表中,s是已经建立的socket。msg是需要发送数据的指针。len是需要发送数据的
长度。这个长度可以用sizeof函数来取得。
7.信息发送函数和读取函数:
数据传输函数write与read:在前面的章节讲述过,write函数可以向文件中写入数据,read
函数可以从文件中读取数据。socket建立连接以后,向这个socket中写入数据表示向远程主
机传送数据。从socket中读取数据相关于接受远程主机传送过来的数据。这两个函数的使用
方法如下所示。
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
在参数列表中,fd是已经建立的socket。buf是指向一段内存的指针,count表示buf指向内
存的长度。read函数读取字节时,会把读取的内容保存到buf指向的内存中,然后返回读取
到字节的个数。使用write函数传输数据时,会把buf指针指向的内存中的数据发送到socket
连接的远程主机,然后返回实际发送字节的个数。
服务端代码:
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <fcntl.h>
#include <string.h>
#define PORT 5678
int main()
{
int sockfd,newsockfd,fd;
struct sockaddr_in addr;
int addr_len = sizeof(struct sockaddr_in);
char msgbuffer[10000];
char tmp_file[128], file[128];
ssize_t bytes;
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("create socket");
return 0;
}
bzero(&addr,sizeof(addr));
addr.sin_family =AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(sockfd,(struct sockaddr*)&addr,sizeof(addr))<0)
{
perror("bind socket");
return 0;
if(listen(sockfd,3)<0)
{
perror("listen");
return 0;
}
if((newsockfd = accept (sockfd,(struct sockaddr*)&addr,&addr_len))<0)
{
perror("accept");
return 0;
}
while(1)
{
bytes = recv(newsockfd, msgbuffer, sizeof(msgbuffer),0);
if (bytes<=0)
break;
else if (!strncmp(msgbuffer, "filename", 8))
{
sscanf(msgbuffer, "filename:%s", tmp_file);
printf("the file name which client send is %s\n", tmp_file);
sprintf(file, "/tmp/%s", tmp_file);
fd = open(file, O_CREAT|O_WRONLY);
if (fd>0)
{
printf("open file %s ok!\n", file);
strcpy(msgbuffer, "accepted");
write(newsockfd, msgbuffer, sizeof(msgbuffer));
}
}
else
write(fd, msgbuffer, bytes);
}
printf("%s wrote ok!\n", file);
if (fd>0)
close(fd);
close(newsockfd);
close(sockfd);
return 0;
}
客户端代码:
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#define PORT 5678
int main(int argc, char *argv[])
{
int sockfd,fd;
struct sockaddr_in addr;
int addr_len = sizeof(struct sockaddr_in);
char msgbuffer[10000];
ssize_t bytes;
if (argc<2)
{
printf("input file name please!\n");
return 0;
}
if ((sockfd = socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("create socket");
return 0;
}
bzero(&addr,sizeof(addr));
addr.sin_family =AF_INET;
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (connect(sockfd, (struct sockaddr*)&addr, addr_len)<0)
{
perror("connect");
return 0;
}
sprintf(msgbuffer, "filename:%s", argv[1]);
write(sockfd, msgbuffer, strlen(msgbuffer));
read(sockfd, msgbuffer, sizeof(msgbuffer));
if (!strncmp(msgbuffer, "accepted", 8))
{
fd = open(argv[1], O_RDONLY);
printf("file %s opened!\n", argv[1]);
if (fd>0)
{
while((bytes=read(fd, msgbuffer, sizeof(msgbuffer))>0))
{
send(sockfd, msgbuffer, bytes,0);
}
close(fd);
printf("send file to server ok!\n");
}
}
write(sockfd, msgbuffer, strlen(msgbuffer));
close(sockfd);
return 0;
}
调试过程:
服务器端:
1.用于保存字符的数组给的空间太少,修改为10000后,恢复正常;
2.在接受请求之后没有关闭socket;
3.读取字符的时候用错了函数名字;
客户端:
1.链接的时候套接字的判断条件错误;
总结体会:
一:个人总结:
1.对面向链接的套接字通信有了新的认识;
2.发现在写实验时候还是好多东西不会写,需要翻课本,需要请教同学;
3.好多东西上课听下就很容易学会了,但是不上心,需要下去下很大的功夫才能完成。 二:知识点总结:
1.绑定描述:
函数bind可以将一个端口绑定到一个已经建立的socket上,这个函数的使用方法如下所示。 int bind(int sockfd,struct sockaddr * my_addr,int addrlen);
参数列表中,sockfd是已经建立的socket编号。sockaddr是一个指向sockaddr结构体类型的
指针。sockaddr的定义方法如下所示。
struct sockaddr
{
unsigned short int sa_family;
char sa_data[14];
};
2.监听函数:
listen函数用于实现监听等待功能。这个函数的使用方法如下所示。
int listen(int s,int backlog);
在参数列表中,s是已经建立的socket。backlog是能同时处理的最大连接请求。如
果超过这个数目,客户端将会接收到ECONNREFUSED拒绝连接的错误。
3.接受链接请求函数:
接受连接请求的函数是accept,这个函数的使用方法如下所示。
int accept(int s,struct sockaddr * addr,int * addrlen);
在参数列表中,s是处于监听状态的socket。addr是一个sockaddr结构体类型的指针,系统
会把远程主机的这些信息保存到这个结构体指针上。addrlen是sockaddr的内存长度,可以
用sizeof函数来取得。
4.请求链接函数:
connect函数可以完成请求连接的功能,这个函数的使用方法如下所示。
int connect (int sockfd,struct sockaddr * serv_addr,int addrlen);
在参数列表中,sockfd是已经建立的socket。serv_addr是一个结构体指针,指向一个
sockaddr结构体。这个结构体存储着远程服务器的IP与端口信息。addrlen是sockaddr结构
体的内存长度,可以用sizeof函数来获取。
5.接受发来的数据函数:
函数recv可以接收远程主机发送来的数据,并把这些数据保存到一个数组中。该函数的使用
方法如下所示。
int recv(int s,void *buf,int len,unsigned int flags);
在参数列表中,s是已经建立的socket。buf是一个指针,指向一个数组。接收到的数据会保
存到这个数组上。len是数组的长度,可以用sizeof函数来取得。
6.信息发送函数send:
用connect函数连接到远程计算机以后,可以用send函数将信息发送到对方的计算机。这个
函数的使用方法如下所示。
int send(int s,const void * msg,int len,unsigned int flags);
在参数列表中,s是已经建立的socket。msg是需要发送数据的指针。len是需要发送数据的
长度。这个长度可以用sizeof函数来取得。
7.信息发送函数和读取函数:
数据传输函数write与read:在前面的章节讲述过,write函数可以向文件中写入数据,read
函数可以从文件中读取数据。socket建立连接以后,向这个socket中写入数据表示向远程主
机传送数据。从socket中读取数据相关于接受远程主机传送过来的数据。这两个函数的使用
方法如下所示。
ssize_t write(int fd, const void *buf, size_t count);
ssize_t read(int fd, void *buf, size_t count);
在参数列表中,fd是已经建立的socket。buf是指向一段内存的指针,count表示buf指向内
存的长度。read函数读取字节时,会把读取的内容保存到buf指向的内存中,然后返回读取
到字节的个数。使用write函数传输数据时,会把buf指针指向的内存中的数据发送到socket
连接的远程主机,然后返回实际发送字节的个数。
正在阅读:
linux面向连接的套接字编程06-03
申论社会热点原因与对策整理05-14
六个核心制度09-16
关于诚信的六个小故事11-20
电影《地雷战》个人观后感参考例文2022年八篇精选08-03
试用期后试题09-27
上海市危险化学品安全管理办法(上海市人民政府令第56号)05-18
新课程背景下小学教师专业化发展研究08-07
- 教学能力大赛决赛获奖-教学实施报告-(完整图文版)
- 互联网+数据中心行业分析报告
- 2017上海杨浦区高三一模数学试题及答案
- 招商部差旅接待管理制度(4-25)
- 学生游玩安全注意事项
- 学生信息管理系统(文档模板供参考)
- 叉车门架有限元分析及系统设计
- 2014帮助残疾人志愿者服务情况记录
- 叶绿体中色素的提取和分离实验
- 中国食物成分表2020年最新权威完整改进版
- 推动国土资源领域生态文明建设
- 给水管道冲洗和消毒记录
- 计算机软件专业自我评价
- 高中数学必修1-5知识点归纳
- 2018-2022年中国第五代移动通信技术(5G)产业深度分析及发展前景研究报告发展趋势(目录)
- 生产车间巡查制度
- 2018版中国光热发电行业深度研究报告目录
- (通用)2019年中考数学总复习 第一章 第四节 数的开方与二次根式课件
- 2017_2018学年高中语文第二单元第4课说数课件粤教版
- 上市新药Lumateperone(卢美哌隆)合成检索总结报告
- 套接字
- 面向
- 连接
- 编程
- linux
- 营销师基础知识第一章市场营销基本理念综合测试题
- 核电SA508_3钢焊接连续冷却转变曲线的分析
- 土地资源管理专业考试知识(事业单位考试)
- 英语词汇词根大全
- 2011-公立医院补偿机制改革的国际经验与启示
- 特发性血小板减少性紫癜
- 昆明粗粮深加工项目商业计划书
- 项目的可行性分析报告范文
- 武汉市部分重点中学2014-2015学年度上学期高一期中考试
- 商户操作平台+POS终端使用手册
- 2016-2022年中国体育俱乐部市场深度调研及投资策略分析报告
- 未婚基督徒对婚姻的祷告
- 中华人民共和国行政强制法
- 当代大学生道德现状调查
- 电子文件归档与管理规范
- 国内养老地产发展模式研究
- 最新日语三级词汇
- VBNET数据库编程基础教程
- 公路养护工中级 复习题
- Tests and numerical simulation of aerodynamic characteristics of airfoils for general aviation