C语言学习笔记-网络与套接字

全部程序都须要编写检查错误的代码linux

一.基础知识服务器

客户端与服务器之间将展开一段结构化对话,叫协议。网络

在C语言中,若是写一个与网络通讯的程序,就须要新的数据流-套接字,套接字是双向的,既能够输入也能够输出数据结构

1.使用socket()函数建立一个套接字数据流socket

#include <sys/socket.h>

int xxxx = socket(PF_INET, SOCK_STREAM, 0);

xxxx是套接字名字函数

套接字与客户端程序通讯,服务器须要经历,绑定端口,监听,接受链接,开始通讯,四个阶段spa

服务启动时,服务器会为每项服务分配一个端口,服务器启动时,须要告诉操做系统将要使用哪一个端口,这个过程叫作端口绑定。操作系统

2.这些代码将建立一个表示"互联网xxx端口"的套接字名code

#include <arpa/inet.h>

struct sockeaddr_in xxxx;

xxxx.sin_family = PF_INET;

xxxx.sin+port = (in_port_t)htons(端口号);

xxxx.sin_addr.s_addr = htonl(INADDR_ANY);

int x = bind (套接字名字, (struct sockaddr * ) &xxxx, sizeof(name));

3.设置客户端链接服务器的排队数量blog

listen(套接字名字, xx)

xx为人数

在linux操做系统的/etc/services文件中能够查看经常使用服务使用的端口号

4.保存链接客户端的详细信息

struct sockaddr_storage xxxx;
unsigned int address_size = sizeof(client_addr);
int connect_d = accept(listener_d, (struct sockaddr *) &client_addr, &address_size);

套接字的输出方法:

二.使用send()函数写数据

send(套接字名称, xxxx, strlen(xxx), 0)

xxx和strlen(xxx)是消息和消息长度

0是高级参数填0便可

绑定端口有延时的解决办法,当使用某个端口绑定了套接字后,在接下来的30秒内,操做系统不容许任何程序绑定它,包括上次绑定这个端口的程序,咱们在绑定前设置套接字的某个选项,就能够解决这个问题了。

int reuse = 1;

setsockopt(套接字名字, SQL_SOCKET, SO_REUSEADDR, (char * )&reuse, sizeof(int));

三.使用recv()函数读数据

recv (接收的描述符,字符变量的缓冲区,<要读取几个字节>, 0);

1.字符串不以\0结尾

2.当用户在客户端输入文本时用\r\n结尾

3.recv()将返回字符个数,若是发生错误就返回-1,若是客户端关闭链接就返回0

4.recv调用不必定能一次接收全部字符,须要配合循环,读取字符。

例如:

int read_in (int socket, char * buf, int len)

{

int c = recv(socket, buf, len, 0);

}

四.为每一个客服端复制一份子进程

服务器在运行一份套接字进程给第一个用户时,没法运行第二个进程给第二个用户,所以使用fork()为每一个用户建立一个子进程。

服务器父进程只须要用主监听套接字,所以关闭副套接字,子进程需处理副套接字,关闭主监听套接字

五.建立ip地址套接字

1.客户端套接字的建立:

int xxx = socket (PF_INET, SOCK_STREAM, 0);

2.客户端和服务器处理套接字的方法不一样,服务器会把套接字绑定到本地端口,而客户端会把套接字链接至远程端口。

struct sockaddr_in xxx;

memset(&xxx, 0, sizeof(xxx));

xxx.sin_family = PF_INET;

xxx.sin_addr.s_addr = inet_addr("ip地址");

xxx.sin_port = htons(端口号);

connect(xxx, (struct sockaddr *) &xxx, sizeof(xxx)); 链接套接字至远程端口

六.使用域名建立套接字

域名系统,计算机发送数据包时须要在地址一栏填写数字形式的ip地址,而dns能够把域名转化为ip地址

建立域名套接字:

#include<netdb.h>

struct addrinfo * xxx;

struct addrinfo xxxx;

memset(&xxxx, 0, sizeof(xxxx));

xxxx.ai_family = PF_UNSPEC;

xxxx.ai_socktype = SOCK_STREAM;

getaddrinfo("域名", "端口", &xxxx, &xxx);

getaddrinfo会在堆上建立一个xxx名字的新数据结构给定域名和端口号。

随后建立套接字

int x = socket(xxx->ai_family, xxx->ai_socktype, xxx->ai_protocal);

connect(x, xxx->ai_addr, xxx->ai_addrlen);

freeaddrinfo(xxx);链接之后删除地址数据
相关文章
相关标签/搜索