【C++】Socket编程记录

318 Views

参考:
https://www.cnblogs.com/kefeiGame/p/7246942.html
https://www.cnblogs.com/kefeiGame/p/7246942.html
https://blog.csdn.net/al_xin/article/details/39051193

socket:

结构体:


/*为套接字储存套接字地址信息*/
struct sockaddr {
  unsigned short sa_family; /* 地址家族, AF_xxx */
  char sa_data[14]; /*14字节协议地址*/
};

/*套接字的基本结构*/
struct sockaddr_in {
  short int sin_family; /* 通信类型 */
  unsigned short int sin_port; /* 端口 */
  struct in_addr sin_addr; /* Internet 地址 */
  unsigned char sin_zero[8]; /* 与sockaddr结构的长度相同*/
};

/*套接字的Internet地址(网络字节顺序)*/
struct in_addr {
  unsigned long s_addr;
};

常用函数:


/*创建一个嵌套口,错误时return -1*/
int socket(int domain, int type, int protocol);
domain: 地址描述,默认值AF_INET
type: 嵌套口的类型,主要是SOCK_STREAM(TCP)和SOCK_DGRAM(UDP) 
protocol: 嵌套口使用的协议,默认0

/*嵌套字和端口绑定,listen前必须bind,错误时return -1*/
int bind(int sockfd, struct sockaddr *my_addr, int addrlen);
sockfd: socket()后的返回值
my_addr: sockaddr 的指针
addrlen: 默认值sizeof(struct sockaddr)

/*建立连接*/
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
参数与bind相同

/*发送、接受数据*/
int send(int sockfd, const void *msg, int len, int flags);//TCP
int recv(int sockfd, void *buf, int len, unsigned int flags);//TCP
int sendto(int sockfd, const void *msg, int len, unsigned int flags,const struct sockaddr *to, int tolen);//UDP
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int *fromlen);//UDP
sockfd: socket()后的返回值
msg: 发送数据的指针
len: 数据长度
flags: 调用的执行方式,默认0
to/from: sockaddr指针
tolen/fromlen: 默认值sizeof(struct sockaddr)

其他:


//132.241.5.10->168161668
ip地址转换为网络字节顺序的地址:inet_addr(ip地址);
//168161668->132.241.5.10
网络字节地址转换为ip地址:inet_ntoa(ina.sin_addr);

htons()--"Host to Network Short"
htonl()--"Host to Network Long"
ntohs()--"Network to Host Short"
ntohl()--"Network to Host Long"

sockaddr_in.sin_port = 0; /* 随机选择一个没有使用的端口 */
sockaddr_in.sin_addr.s_addr = INADDR_ANY; /* 使用自己的IP地址 */

多线程:

两种执行方式:
detach方式,启动的线程自主在后台运行,当前的代码继续往下执行,不等待新线程结束。前面代码所使用的就是这种方式。
join方式,等待启动的线程完成,才会继续往下执行。假如前面的代码使用这种方式,其输出就会0,1,2,3,因为每次都是前一个线程输出完成了才会进行下一个循环,启动下一个新线程。

线程默认拷贝对象,即使传入的是引用,除非使用ref函数


class _tagNode
{
public:
    int a;
    int b;
};

void func(_tagNode &node)
{
    node.a = 10;
    node.b = 20;
}

void f()
{
    _tagNode node;
    thread t(func, node);
    // thread t(func,std::ref(node));
    t.join();
    cout << node.a << endl ;
    cout << node.b << endl ;
}

留下回复

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据