最近在学习Linux系统编程和网络编程,记录一下学习过程中写过的程序,编程语言为C++,系统为Ubuntu 20.04.2 LTS
1.socket通信
源代码
服务器端源代码
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-21 14:06:19
* @ Modified Time: 2021-07-21 16:51:53
* @ Description : socket通信,实现字符串转换,服务器端代码
*/
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <cctype>
#include <cstring>
#include <sys/socket.h>
#include <arpa/inet.h>
using namespace std;
const int server_port = 9527;
int main(int argc, char* argv[]){
printf("-----This is server-----\n");
int lfd = socket(AF_INET,SOCK_STREAM,0);
if(lfd == -1){
perror("socket error");
exit(1);
}
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(server_port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int ret = bind(lfd,reinterpret_cast<sockaddr*>(&serv_addr),sizeof(serv_addr));
if(ret == -1){
perror("bind error");
exit(1);
}
ret = listen(lfd,128);
if(ret == -1){
perror("listen error");
exit(1);
}
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int cfd = accept(lfd,reinterpret_cast<struct sockaddr*>(&client_addr),&client_addr_len);
if(cfd == -1){
perror("accept error");
exit(1);
}
char client_ip[BUFSIZ];
printf("client ip = %s, port = %d\n",
inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_ip,sizeof(client_ip)),
ntohs(client_addr.sin_port));
char buf[BUFSIZ];
int num=0,count = 10;
while(--count){
num = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,num);
for(int i=0;i<num;++i){
buf[i] = toupper(buf[i]);
}
write(cfd,buf,num);
}
close(lfd);
close(cfd);
printf("-----connection closed-----\n");
return 0;
}
客户端源代码
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-21 14:53:01
* @ Modified Time: 2021-07-21 16:55:45
* @ Description : socket通信,实现字符串转换,客户端代码
*/
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
using namespace std;
const int server_port = 9527;
int main(int argc, char* argv[]){
printf("-----This is client-----\n");
int cfd = socket(AF_INET,SOCK_STREAM,0);
if(cfd == -1){
perror("socket error");
exit(1);
}
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr);
int ret = connect(cfd,reinterpret_cast<struct sockaddr*>(&server_addr),sizeof(server_addr));
if(ret != 0){
perror("connect error");
exit(1);
}
int count= 10,num = 0;
char buf[BUFSIZ];
while(--count){
write(cfd,"hello\n",6);
num = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,num);
sleep(1);
}
close(cfd);
printf("-----connection closed-----\n");
return 0;
}
运行结果
2.Socket通信 封装错误处理函数
源代码
封装错误处理 头文件wrap.h
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 10:25:18
* @ Modified Time: 2021-07-22 15:01:15
* @ Description : Socket通信 封装错误处理
*/
#ifndef _WRAP_H_
#define _WRAP_H_
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <cctype>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
using std::string;
void errorHandle(const string str);
int Socket(int domain, int type, int protocol);
void Bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
void Listen(int sockfd, int backlog);
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
void Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
#endif
封装错误处理 源文件wrap.cpp
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 10:25:28
* @ Modified Time: 2021-07-22 12:02:07
* @ Description : 封装函数,添加错误处理,使代码逻辑更清晰
*/
#include "wrap.h"
void errorHandle(const string str){ //输出错误信息,并退出程序
perror(str.c_str());
exit(1);
}
int Socket(int domain, int type, int protocol){
int lfd = socket(domain,type,protocol);
if(lfd == -1){
errorHandle("socket error");
}
return lfd;
}
void Bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen){
int ret = bind(sockfd,addr,addrlen);
if(ret == -1){
errorHandle("bind error");
}
}
void Listen(int sockfd, int backlog){
int ret = listen(sockfd,backlog);
if(ret != 0){
errorHandle("listen error");
}
}
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen){
int cfd = accept(sockfd,addr,addrlen);
if(cfd == -1){
errorHandle("accept error");
}
return cfd;
}
void Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
int ret = connect(sockfd, addr, addrlen);
if(ret != 0){
errorHandle("connect error");
}
}
服务器端源程序
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-21 14:06:19
* @ Modified Time: 2021-07-22 14:47:43
* @ Description : socket通信,实现字符串转换,服务器端代码
*/
#include "wrap.h"
using namespace std;
const int server_port = 9529;
int main(int argc, char* argv[]){
printf("-----This is server-----\n");
int lfd = Socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(server_port);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(lfd,reinterpret_cast<struct sockaddr*>(&serv_addr),sizeof(serv_addr));
Listen(lfd,128);
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
int cfd = Accept(lfd, reinterpret_cast<struct sockaddr*>(&client_addr), &client_addr_len);
char client_ip[BUFSIZ];
printf("client ip = %s, port = %d\n",
inet_ntop(AF_INET,&client_addr.sin_addr.s_addr,client_ip,sizeof(client_ip)),
ntohs(client_addr.sin_port));
char buf[BUFSIZ];
int num=0,count = 10;
while(--count){
num = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,num);
for(int i=0;i<num;++i){
buf[i] = toupper(buf[i]);
}
write(cfd,buf,num);
}
close(lfd);
close(cfd);
printf("-----connection closed-----\n");
return 0;
}
客户端源程序
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-21 14:53:01
* @ Modified Time: 2021-07-22 14:47:49
* @ Description : socket通信,实现字符串转换,客户端代码
*/
#include "wrap.h"
using namespace std;
const int server_port = 9529;
int main(int argc, char* argv[]){
printf("-----This is client-----\n");
int cfd = Socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr);
Connect(cfd,reinterpret_cast<struct sockaddr*>(&server_addr),sizeof(server_addr));
int count= 10,num = 0;
char buf[BUFSIZ];
while(--count){
write(cfd,"hello\n",6);
num = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,num);
sleep(1);
}
close(cfd);
printf("-----connection closed-----\n");
return 0;
}
编译命令
g++ 1.socket_server.cpp wrap.cpp -o server
g++ 1.socket_client.cpp wrap.cpp -o client
运行结果
3.多线程Socket通信
源代码
封装错误处理 头文件wrap.h
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 10:25:18
* @ Modified Time: 2021-07-22 15:01:15
* @ Description : Socket通信 封装错误处理
*/
#ifndef _WRAP_H_
#define _WRAP_H_
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <cctype>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
using std::string;
void errorHandle(const string str);
int Socket(int domain, int type, int protocol);
void Bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
void Listen(int sockfd, int backlog);
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
void Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
#endif
封装错误处理 源文件wrap.cpp
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 10:25:28
* @ Modified Time: 2021-07-22 12:02:07
* @ Description : 封装函数,添加错误处理,使代码逻辑更清晰
*/
#include "wrap.h"
void errorHandle(const string str){ //输出错误信息,并退出程序
perror(str.c_str());
exit(1);
}
int Socket(int domain, int type, int protocol){
int lfd = socket(domain,type,protocol);
if(lfd == -1){
errorHandle("socket error");
}
return lfd;
}
void Bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen){
int ret = bind(sockfd,addr,addrlen);
if(ret == -1){
errorHandle("bind error");
}
}
void Listen(int sockfd, int backlog){
int ret = listen(sockfd,backlog);
if(ret != 0){
errorHandle("listen error");
}
}
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen){
int cfd = accept(sockfd,addr,addrlen);
if(cfd == -1){
errorHandle("accept error");
}
return cfd;
}
void Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
int ret = connect(sockfd, addr, addrlen);
if(ret != 0){
errorHandle("connect error");
}
}
服务器端源程序
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 14:15:56
* @ Modified Time: 2021-07-22 15:09:50
* @ Description : 多线程socket通信 服务器端
*/
#include "wrap.h"
#include <strings.h>
#include <pthread.h>
using namespace std;
const int server_port = 9999; //服务器端口号
struct s_info{
struct sockaddr_in addr;
int cfd;
};
void* func(void* arg){
struct s_info *t = reinterpret_cast<struct s_info*>(arg);
char buf[BUFSIZ];
int n, i;
while(true){
n = read(t->cfd,buf,BUFSIZ);
if(n == 0){
cout<<"----------client "<< t->cfd <<" losed.\n";
break;
}
for(i=0;i<n;++i){
buf[i] = toupper(buf[i]); //小写转大写
}
write(STDOUT_FILENO,buf,n); //打印到屏幕
write(t->cfd,buf,n);
}
close(t->cfd);
pthread_exit(nullptr);
}
int main(int argc, char* argv[]){
cout<<"-----This is server.-----\n";
int lfd = Socket(AF_INET, SOCK_STREAM, 0);
s_info st[256];
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(lfd,reinterpret_cast<struct sockaddr*>(&server_addr),sizeof(server_addr));
Listen(lfd,128);
int i = 0, cfd;
char tmp[16];
pthread_t tid;
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
while(true){
cfd = Accept(lfd,reinterpret_cast<struct sockaddr*>(&client_addr),&client_addr_len);
st[i].addr = client_addr;
st[i].cfd = cfd;
cout<<"received from "<<inet_ntop(AF_INET,&(st[i]).addr.sin_addr,tmp,sizeof(tmp))
<<", port : "<<ntohs((st[i]).addr.sin_port)<<"\n";
pthread_create(&tid,nullptr,func,reinterpret_cast<void*>(&st[i]));
pthread_detach(tid);
}
close(lfd);
pthread_exit(nullptr);
}
客户端源程序
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-21 14:53:01
* @ Modified Time: 2021-07-22 15:11:08
* @ Description : socket通信,实现字符串转换,客户端代码
*/
#include "wrap.h"
using namespace std;
const int server_port = 9999;
int main(int argc, char* argv[]){
printf("-----This is client-----\n");
int cfd = Socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr); //本地 127.0.0.1
Connect(cfd,reinterpret_cast<struct sockaddr*>(&server_addr),sizeof(server_addr));
int count= 10,num = 0;
char buf[BUFSIZ];
string str;
while(true){
cin>>str;
if(str == "quit"){ //输入quit,关闭客户端
break;
}
str+='\n';
write(cfd,str.c_str(),str.size());
num = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,num);
}
close(cfd);
printf("-----connection closed-----\n");
return 0;
}
编译命令
g++ 2.multi_socket_server.cpp wrap.cpp -pthread -o server
g++ 2.multi_socket_client.cpp wrap.cpp -o client
运行结果
4.socket通信、端口复用
源代码
错误处理 头文件wrap.h
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 10:25:18
* @ Modified Time: 2021-07-22 15:01:15
* @ Description : Socket通信 封装错误处理
*/
#ifndef _WRAP_H_
#define _WRAP_H_
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <cctype>
#include <cstring>
#include <string>
#include <sys/socket.h>
#include <arpa/inet.h>
using std::string;
void errorHandle(const string str);
int Socket(int domain, int type, int protocol);
void Bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
void Listen(int sockfd, int backlog);
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
void Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
#endif
错误处理源文件wrap.cpp
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 10:25:28
* @ Modified Time: 2021-07-22 12:02:07
* @ Description : 封装函数,添加错误处理,使代码逻辑更清晰
*/
#include "wrap.h"
void errorHandle(const string str){ //输出错误信息,并退出程序
perror(str.c_str());
exit(1);
}
int Socket(int domain, int type, int protocol){
int lfd = socket(domain,type,protocol);
if(lfd == -1){
errorHandle("socket error");
}
return lfd;
}
void Bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen){
int ret = bind(sockfd,addr,addrlen);
if(ret == -1){
errorHandle("bind error");
}
}
void Listen(int sockfd, int backlog){
int ret = listen(sockfd,backlog);
if(ret != 0){
errorHandle("listen error");
}
}
int Accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen){
int cfd = accept(sockfd,addr,addrlen);
if(cfd == -1){
errorHandle("accept error");
}
return cfd;
}
void Connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
int ret = connect(sockfd, addr, addrlen);
if(ret != 0){
errorHandle("connect error");
}
}
服务器端源代码
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-22 14:15:56
* @ Modified Time: 2021-07-23 14:29:40
* @ Description : 多线程socket通信 服务器端
*/
#include "wrap.h"
#include <strings.h>
#include <pthread.h>
using namespace std;
const int server_port = 9999; //服务器端口号
struct s_info{
struct sockaddr_in addr;
int cfd;
};
void* func(void* arg){
struct s_info *t = reinterpret_cast<struct s_info*>(arg);
char buf[BUFSIZ],str[16];
int n, i;
while(true){
n = read(t->cfd,buf,BUFSIZ);
if(n == 0){
cout<<"----------client "<< t->cfd <<" losed.\n";
break;
}
for(i=0;i<n;++i){
buf[i] = toupper(buf[i]); //小写转大写
}
cout<<"received from client " << t->cfd <<", ip: "<<inet_ntop(AF_INET,&t->addr.sin_addr.s_addr,str,sizeof(str))
<<", port: "<<ntohs(t->addr.sin_port)<<"\n";
write(STDOUT_FILENO,buf,n); //打印到屏幕
write(t->cfd,buf,n);
}
close(t->cfd);
pthread_exit(nullptr);
}
int main(int argc, char* argv[]){
cout<<"-----This is server.-----\n";
int lfd = Socket(AF_INET, SOCK_STREAM, 0);
int opt = 1; //设置端口复用
setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,reinterpret_cast<void*>(&opt),sizeof(opt));
s_info st[256];
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
Bind(lfd,reinterpret_cast<struct sockaddr*>(&server_addr),sizeof(server_addr));
Listen(lfd,128);
int i = 0, cfd;
char tmp[16];
pthread_t tid;
struct sockaddr_in client_addr;
socklen_t client_addr_len = sizeof(client_addr);
while(true){
cfd = Accept(lfd,reinterpret_cast<struct sockaddr*>(&client_addr),&client_addr_len);
st[i].addr = client_addr;
st[i].cfd = cfd;
pthread_create(&tid,nullptr,func,reinterpret_cast<void*>(&st[i]));
pthread_detach(tid);
++i;
}
close(lfd);
pthread_exit(nullptr);
}
客户端源代码
/**
* @ Author: WangYusong
* @ E-Mail: admin@wangyusong.cn
* @ Create Time : 2021-07-21 14:53:01
* @ Modified Time: 2021-07-23 14:29:43
* @ Description : socket通信,实现字符串转换,客户端代码
*/
#include "wrap.h"
using namespace std;
const int server_port = 9999;
int main(int argc, char* argv[]){
printf("-----This is client-----\n");
int cfd = Socket(AF_INET,SOCK_STREAM,0);
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(server_port);
inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr); //本地 127.0.0.1
Connect(cfd,reinterpret_cast<struct sockaddr*>(&server_addr),sizeof(server_addr));
int count= 10,num = 0;
char buf[BUFSIZ];
string str;
while(true){
cin>>str;
if(str == "quit"){ //输入quit,关闭客户端
break;
}
str+='\n';
write(cfd,str.c_str(),str.size());
num = read(cfd,buf,sizeof(buf));
write(STDOUT_FILENO,buf,num);
}
close(cfd);
printf("-----connection closed-----\n");
return 0;
}