https://gitee.com/vtenten/cppd/tree/master/socket-example
TCP/server.cpp
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<unistd.h>
#define MAXLINE 4096
int main(int argc, char** argv){
// ------------------ 声明/初始化变量 -----------------------------
int listenfd; // 监听的描述符
int connfd; // 连接的描述符
int end_position; // 接收数据的结束位置
char buff[4096]; // 接收数据
struct sockaddr_in servaddr; // 地址结构体
memset(&servaddr, 0, sizeof(servaddr)); // 重置内存数据为0,这一步是以防万一的操作
servaddr.sin_family = AF_INET; // IPV4协议
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听 0.0.0.0
servaddr.sin_port = htons(10233); // 端口号为 10233
// sockaddr 和 sockaddr_in 类 数据结构是一样的,就是名字不同
// 为了防止警告/编译错误,不能混用,需要使用时 要进行类型转换
// (struct sockaddr *)&servaddr
// ------------------ 创建套接字 -----------------------------
/* socket(AF_INET,SOCK_STREAM,0)
* AF_INET IPV4
* SOCK_STREAM TCP
* 0 协议编号,一般不需要特殊设置,设置为0即可
* if语句还可以这样写 if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ ... }
*/
listenfd = socket(AF_INET,SOCK_STREAM,0);
if(listenfd == -1 ){
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
// ------------------ 绑定ip地址和端口号 ------------------
if( bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){
printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
// ------------------ 进行监听 ------------------
// 10 表示可接收的连接数
if( listen(listenfd, 10) == -1){
printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
// ------------------ 等待用户连接 ------------------
printf("======waiting for client's request======\n");
while(1){
if( (connfd = accept(listenfd, (struct sockaddr*)NULL, NULL)) == -1){
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
continue;
}
// -------------- 用户连接后 接收数据 ---------------
// 返回接收的字符数 n+1,到时候我们将buff[n+1]='\n',\n表示结束符
end_position = recv(connfd, buff, MAXLINE, 0);
buff[end_position] = '\0';
printf("recv msg from client: %s", buff);
// -------------- 向用户返回数据 ---------------
// 原样返回
send(connfd, buff, strlen(buff), 0);
// ------------- 关闭用户连接套接字 ---------------
close(connfd);
}
// ------------------ 关闭监听套接字 ------------------
close(listenfd);
return 0;
}
TCP/client.cpp
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#define MAXLINE 4096
int main(int argc, char** argv){
// main 函数
// int argc 参数个数,执行文件本身为第一个,参数的第一个为2
// char** argv 参数的值, argv[0] argv[1]
// ----------------- 检查命令行参数 -----------------
if( argc != 2){
printf("usage: ./client <ipaddress>\n");
return 0;
}
// ------------------ 声明/初始化变量 -----------------------------
int sockfd ;
int end_index;
char recvline[4096], sendline[4096];
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(10233);
if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
printf("inet_pton error for %s\n",argv[1]);
return 0;
}
// ------------------ 创建套接字 -----------------------------
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
return 0;
}
// ------------------ 连接服务器 -----------------------------
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
// ------------------ 发送消息 -----------------------------
printf("send msg to server: \n");
fgets(sendline, 4096, stdin); // 获取终端输入
if( send(sockfd, sendline, strlen(sendline), 0) < 0){
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return 0;
}
// ------------------ 接收消息 -----------------------------
end_index = recv(sockfd, recvline, MAXLINE, 0);
recvline[end_index] = '\0';
printf("recv msg from client: %s\n", recvline);
// ------------------ 关闭套接字,断开连接 --------------------
close(sockfd);
return 0;
}
UDP/server.cpp
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define SERV_PORT 9003
int main()
{
// ------------------- 声明/初始化变量 ---------------------------------
int sock_fd;
int len; // sizeof(addr_serv)
struct sockaddr_in addr_serv;
struct sockaddr_in addr_client;
int send_num;
int recv_num;
char recv_buf[4096];
// char send_buf[512]; // 我们接收什么返回什么,所以这个不需要
memset(&addr_serv, 0, sizeof(addr_serv));
addr_serv.sin_family = AF_INET; //使用IPV4地址
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); //0.0.0.0
addr_serv.sin_port = htons(SERV_PORT); //端口号 9003
len = sizeof(addr_serv);
// ------------------- 创建udp套接字 ---------------------------------
if( (sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("socket");
exit(1);
}
// ------------------- 绑定端口号 ---------------------------------
if(bind(sock_fd, (struct sockaddr *)&addr_serv, sizeof(addr_serv)) < 0)
{
perror("bind error:");
exit(1);
}
while(1)
{
// ----------------- 接收数据 ---------------------------------
printf("server wait:\n");
recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_client, (socklen_t *)&len);
// UDP套接字不会保持连接状态,每次传输数据都要添加目标地址信息,这相当于在邮寄包裹前填写收件人地址。
if(recv_num < 0)
{
perror("recvfrom error:");
exit(1);
}
recv_buf[recv_num] = '\0';
printf("server receive %d bytes: %s\n", recv_num, recv_buf);
// ----------------- 发送 返回消息 ---------------------------------
// 发的什么 我返回什么 sizeof(recv_buf) recv_num
send_num = sendto(sock_fd, recv_buf, recv_num, 0, (struct sockaddr *)&addr_client, len);
if(send_num < 0)
{
perror("sendto error:");
exit(1);
}
}
// ------------------- 关闭套接字 ---------------------------------
close(sock_fd);
return 0;
}
UDP/client.cpp
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DEST_PORT 9003
#define DSET_IP_ADDRESS "127.0.0.1"
int main()
{
// ------------------- 声明/初始化变量 ---------------------------------
int sock_fd;
char send_buf[4096];
char recv_buf[4096];
int send_num;
int recv_num;
int len;
struct sockaddr_in addr_serv;
memset(&addr_serv, 0, sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
addr_serv.sin_port = htons(DEST_PORT);
len = sizeof(addr_serv);
// ------------------- 创建udp套接字 ---------------------------------
sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(sock_fd < 0)
{
perror("socket");
exit(1);
}
// ------------------- 直接发送数据 ---------------------------------
printf("send msg to server: \n");
fgets(send_buf, 4096, stdin); // 获取终端输入
send_num = sendto(sock_fd, send_buf, strlen(send_buf), 0, (struct sockaddr *)&addr_serv, len);
if(send_num < 0)
{
perror("sendto error:");
exit(1);
}
// ------------------- 接收 返回数据 ---------------------------------
recv_num = recvfrom(sock_fd, recv_buf, sizeof(recv_buf), 0, (struct sockaddr *)&addr_serv, (socklen_t *)&len);
if(recv_num < 0)
{
perror("recvfrom error:");
exit(1);
}
recv_buf[recv_num] = '\0';
printf("client receive %d bytes: %s\n", recv_num, recv_buf);
// ------------------- 关闭套接字 ---------------------------------
close(sock_fd);
return 0;
}