突发疫情但挡不住我们学习的脚步,目前疫情好转,宅了将近一个多月的自己终于可以出去戴着口罩出去走走了!!!
接上
Linux学习笔记(一)
Linux学习笔记(二)
Linux学习笔记(三):函数、文件IO和线程
Linux学习笔记(四):信息量、同步、互斥和网络编程
P操作 V操作
以下主要是对服务器和客户端复习介绍:
1、服务器:server
//建立连接
(1)socket( );//创建套接字
声明:int socket(int domain, int type,int protocol)
int sock = socket(PF_INET,SOCK_STREAM,0);
(2)bind( );//绑定自己的IP
声明:int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
bind(sock,(struct sockaddr*)(&myaddr),sizeof(myaddr));
sockfd:是由socket调用返回的文件描述符.
addrlen:是sockaddr结构的长度.
my_addr:是一个指向sockaddr的指针. 在中有 sockaddr的定义
(3)listen( );//监听是否有客户端向服务器发起连接
声明:int listen(int sockfd,int backlog)
sockfd:是bind后的文件描述符.
backlog:设置请求排队的最大长度.当有多个客户端程序和服务端相连时, 使用这个表示可以介绍的排队长度. 函数将bind的文件描述符变为监听套接字.返回的情况和bind一样.
(4)accept( );//接受客户端的请求
声明:int accept(int sockfd, struct sockaddr *addr,int *addrlen)
sockfd:是listen后的文件描述符.
addr,addrlen是用来给客户端的程序填写的,服务器端只要传递指针就可了. bind,listen和accept是服务器端用的函数, accept调用时,服务器端的程序会一直阻塞到有一个 客户程序发出了连接. accept成功时返回最后的服务器端的文件描述符, 这个时候服务器端可以向该描述符写信息了. 失败时返回-1。
//接收数据
(5)write( );//send( );
(6)read( );//recv( );
//关闭
(7)close( );
2、客户端:client
//建立连接
(1)socket( );
(2)connect( );//主动发起与服务器的连接
声明:int connect(int sockfd, struct sockaddr * serv_addr,int addrlen)
sockfd:socket返回的文件描述符.
serv_addr:储存了服务器端的连接信息.其中sin_add是服务端的地址
addrlen:serv_addr的长度
connect函数是客户端用来同服务端连接的.成功时返回0,sockfd是同服务端通讯的文件描述符 失败时返回-1.
//接收数据
(3)read( );//recv();
(4)write( );//send();
//关闭
(5)close( );
什么是网络编程呢?????
就是两个进程,跨计算机,他俩需要通讯的话,需要通过网络对接起来。这就是 socket 的作用。打个比方吧,两个进程在两个计算机上,需要有一个进程做被动方,叫做服务器。另一个做主动方,叫做客户端。他们位于某个计算机上,叫做主机 host ,在网络上有自己的 ip 地址。一个计算机上可以有多个进程作为服务器,但是 ip 每个机器只有一个,所以通过不同的 port 数字加以区分。因此,服务器程序需要绑定在本机的某个端口号上。客户端需要声明自己连接哪个地址的那个端口。两个进程通过网络建立起通讯渠道,然后就可以通过 recv send 来收发一些信息,完成通讯。所以 socket 就是指代承载这种通讯的系统资源的标识。
通俗易懂的话转自:https://www.zhihu.com/question/29637351/answer/110219546
客户/服务器模式在TCP/IP网络应用中,通信的两个进程间相互作用的主要模式是客户/服务器(Client/Server, C/S)模式,即客户向服务器发出服务请求,服务器接收到请求后,提供相应的服务。
客户/服务器模式的建立基于以下两点:
(1)首先,建立网络的起因是网络中软硬件资源、运算能力和信息不均等,需要共享,从而造就拥有众多资源的主机提供服务,资源较少的客户请求服务这一非对等作用。
(2)其次,网间进程通信完全是异步的,相互通信的进程间既不存在父子关系,又不共享内存缓冲区,因此需要一种机制为希望通信的进程间建立联系,为二者的数据交换提供同步,这就是基于客户/服务器模式的TCP/IP。
服务器端:其过程是首先服务器方要先启动,并根据请求提供相应服务:
(1)打开一通信通道并告知本地主机,它愿意在某一公认地址上的某端口(如FTP的端口可能为21)接收客户请求;
(2)等待客户请求到达该端口;
(3)接收到客户端的服务请求时,处理该请求并发送应答信号。接收到并发服务请求,要激活一新进程来处理这个客户请求(如UNIX系统中用fork、exec)。新进程处理此客户请求,并不需要对其它请求作出应答。服务完成后,关闭此新进程与客户的通信链路,并终止。
(4)返回第(2)步,等待另一客户请求。
(5)关闭服务器
Server:
int sock = socket(PF_INET,SOCK_STREAM,0);
bind(sock,(struct sockaddr*)(&myaddr),sizeof(myaddr));
struct sockaddr_in myaddr;
myaddr.sin_family = PF_INET;
myaddr.sin_port = htons(8888);
myaddr.sin_addr.s_addr = inet_addr("192.168.13.119");
listen(sock,7);
int connfd = accept(sock,NULL,NULL);
客户端:
(1)打开一通信通道,并连接到服务器所在主机的特定端口;
(2)向服务器发服务请求报文,等待并接收应答;继续提出请求;
(3)请求结束后关闭通信通道并终止。
client:
connect(sock,(struct sockaddr*)(&seraddr),sizeof(seraddr));
send(sock,”hello”,10,0);
recv(sock,buf,sizeof(buf),0);
close(sock);
创建套接字:Int sock = socket(PF_INET,SOCK_STREAM,0);
绑定自己的IP:bind(sock,(struct sockaddr*)(&myaddr),sizeof(myaddr));
主动发起与服务器的连接:struct sockaddr_in myaddr;
myaddr.sin_family = PF_INET;
myaddr.sin_port = htons(8888);
myaddr.sin_addr.s_addr = inet_addr("192.168.13.119");
监听:listen(sock,7);
接受请求:int connfd = accept(sock,NULL,NULL);
发送数据:send(sock,”hello”,10,0);
接收数据:recv(sock,buf,sizeof(buf),0);
发送数据:send(sock,”hello”,10,0);
接收数据:recv(sock,buf,sizeof(buf),0);
特别需要注意的是linux下安装QT需添加的环境配置
1、 在【终端】中执行如下命令:sudo gedit /etc/profile
2、添加如下内容:
针对32位的系统配置:
export QTDIR=/wyj/Qt5.4.1/5.4
export PATH=$QTDIR/gcc/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/gcc/lib:$LD_LIBRARY_PATH
针对64位的系统配置:
export QTDIR=/opt/Qt5.4.1/5.4
export PATH=$QTDIR/gcc_64/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/gcc_64/lib:$LD_LIBRARY_PATH
(1)打开Qt Creator,点击New Project,创建一个新项目:Application->Qt Widgets Appliccation;
(2)项目名称和创建路径自己设置;
(3)Kit Selection选择gcc交叉编译器;
(4)如果系统没有自带openGL库时,在做带有3D效果的界面会报错,手动安装openGL。首先修改系统设置----软件和更新----下载自----中国的服务器。
信号和槽机制就相当于回调函数。在这种机制下,程序员有两次处理事件的机会:
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
#include "JasonQt/JasonQt_Vop.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
// 连接完成函数
void connectDone();
void recvdo();
// 按钮的槽函数
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_5_clicked();
void on_pushButton_6_clicked();
void on_pushButton_7_clicked();
void on_pushButton_4_clicked();
void on_pushButton_4_pressed();
void on_pushButton_4_released();
private:
// tcp连接函数
void tcpConnect();
bool Data_parsing(QByteArray);
private:
Ui::Widget *ui;
QTcpSocket tcpSocket,pic_socket;
QMovie *movie;
QLineEdit *line;
JasonQt_Vop::BaiduVop m_baiduVop;
unsigned int piclen;
char picbuf[1024 * 1024 - 4];
};
#endif // WIDGET_H
在mainwindow.ui界面,添加一个pushbutton按钮,如下
之后在新界面添加textEdit控件用来显示要选择的文件内容,选择之后可以选择layout布局(点击窗口空白部分,然后选择界面上方的布局方式)。
ubuntu下利用ifconfig查看当前网络下的IP地址。
打开两个终端,分别运行服务器和客户端的代码:
服务器:
#include
#include
#include
#include
#include
int main(){
/*1.创建套i接字*/
int sock = socket(PF_INET,SOCK_STREAM,0);
if(sock < 0){
printf("socket error\n");
return -1;
}
printf("socket success\n");
/*2.绑定本地IP*/
struct sockaddr_in myaddr;
myaddr.sin_family = PF_INET;
myaddr.sin_port = htons(8888);// 设置端口号,我这里设置的是8888
myaddr.sin_addr.s_addr = inet_addr("xxx.xxx.xx.xxx");// 设置自己当前网端下的IP地址
if(0 > bind(sock,(struct sockaddr*)(&myaddr),sizeof(myaddr))){
printf("bind error\n");
return -1;
}
printf("bind success\n");
/*3.监听*/
if(0 > listen(sock,10)){
printf("listen error\n");
return -1;
}
printf("listen success\n");
/*4.接受链接请求*/
int connfd = accept(sock,NULL,NULL);
if(connfd < 0){
printf("accept error\n");
return -1;
}
printf("accept success\n");
/*5.数据收发*/
//send()/recv();
char buf[20];
gets(buf);
int ret = send(connfd,buf,sizeof(buf),0);
if(ret < 0){
printf("send error\n");
return -1;
}
printf("send success\n");
/*6.关闭套接字*/
close(connfd);
close(sock);
return 0;
}
客户端:
#include
#include
#include
#include
#include
int main(){
/*1.创建套接字*/
int sock = socket(PF_INET,SOCK_STREAM,0);
if(sock < 0){
printf("sock error\n");
return -1;
}
printf("sock success\n");
/*2.主动发起与服务器的连接*/
struct sockaddr_in seraddr;
seraddr.sin_family = PF_INET;
seraddr.sin_port = htons(8888);
seraddr.sin_addr.s_addr = inet_addr("xxx.xxx.xx.xxx");// 一定与服务器的IP地址一样
if(0 > connect(sock,(struct sockaddr*)(&seraddr),sizeof(seraddr))){
printf("connect errorr\n");
return -1;
}
printf("connect success\n");
/*3.数据收发*/
char buf[20];
int ret = recv(sock,buf,sizeof(buf),0);
if(ret < 0){
printf("recv error\n");
return -1;
}
printf("recv:%s\n",buf);
/*4.关闭套接字*/
close(sock);
return 0;
}
运行结果:
大家的三连击是对我最大的肯定!!!大家不要吝啬自己的鼠标或者手指。。。。。。
待续中。。。。。。