C语言服务器的搭建

服务器:

1 创建套接字---->socket

2 绑定服务器地址--->bind(设置服务器地址struct sockaddr_in)

3 监听---->listen

4 接受---->accept

5 通信---->read/write

客户端:

1 创建套接字---->socket

2 链接--->connect

5 通信---->read/write

服务器

1 创建套接字---->socket

函数原型    //    int socket(int domain, int type, int protocol);

domain    //    AF_INET:使用ipv4协议来实现远程通讯

type    //    SOCK_STREAM:使用可靠传输

protocol    //    0:使用选择传输的默认协议(SOCK_STREAM-->tcp)

int sockFD = socket(AF_INET,SOCK_STREAM,0);


2 绑定服务器地址--->bind(设置服务器地址struct sockaddr_in)

函数原型    //    int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

sockfd    //    为 1 中生成的sockFD

struct sockaddr{

    sa_family_t    sa_family;

    char    sa_data[14];

};

sturct sockaddr_in{

    short    sin_family;//协议

    unsigned short    sin_port;//端口号

    struct in_addr    sin_addr;//ip地址

    unsigned char    sin_zero[8];//为了填空

};

typedef unit_32t in_addr_t;

struct in_addr{

    in_addr_t    s_addr;

};

用 结构体 sockaddr_in 代替 aockaddr ,将数据传入 sockaddr_in。


struct sockaddr_in serAddr;

serAddr.sin_family = AF_INET; //使用ipv4协议通讯

htons:将本地字节序转换成网络字节序 host to network short

serAddr.sin_port = htons(6666);


inet_addr:将点分十进制字符串表示的ip转换成整数

serAddr.sin_addr.s_addr = inet_addr("192.168.137.128");

另外一种设置ip地址的方法

函数原型 int inet_pton(int af, const char *src, void *dst);

inet_pton(AF_INET, "192.168.1.37", &sin.sin_addr.s_addr);


将sockfd和指定的ip,port绑定,这样我们就可以通过sockfd收发该ip,port上的数据

bind(sockFD,(struct sockaddr*)&serAddr,sizeof(serAddr))

注意这里要将 sockaddr_in* 强转为 sockaddr*


3 监听---->listen

函数原型    //    int listen(int sockfd, int backlog);

listen(serSockFD,20);

将sockfd设置为监听状态

20:表示客户端连接缓冲队列的大小


4 接受---->accept

函数原型    //    int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

accept的参数在之前 2 中都已经详细介绍过了。

struct sockaddr_in cliAddr;

int newSockFD = -1;

int iAddrLen = sizeof(cliAddr);

newSockFD = accept(serSockFD,(struct sockaddr*)&cliAddr,&iAddrLen);

若没有客户端连接,则阻塞等待,接收从sockfd监听到的客户端会自动的将连接过来的客户端的ip,port等信息放入clientAddr中。函数成功会自动创建一个socket,专门用于服务器和该客户端数据交互。


5 通信---->read/write

一般将读写将给子进程处理

pthread_t threadForClient;

pthread_create(&threadForClient,NULL,handleClient,(void*)newSockFD);

子进程处理函数

void *handleClient(void *arg)

{

    int sockFD = (int)arg;

    write(sockfd, (char*)sendpdu, sendsize);

    read(sockfd, (char*)revpdu, revsize);

}

客户端

客户端的操作和服务器基本一致,下面是客户端代码:

//1 创建套接字

int socket(int domain, int type, int protocol);

int ser_fd = socket(AF_INET, SOCK_STREAM, 0); //tcp

if(ser_fd < 0){

return -1;

}

//设置服务器地址

struct sockaddr_in sin;

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

sin.sin_family = AF_INET; //设置协议族

sin.sin_port = htons(5555); //设置端口号(大端字节序)

//设置ip地址

int inet_pton(int af, const char *src, void *dst);

if(inet_pton(AF_INET, "192.168.1.37", &sin.sin_addr.s_addr) < 0){

return -1;

}

//2 链接服务器

int connect(int sockfd, const struct sockaddr *addr,

                  socklen_t addrlen);

if(connect(ser_fd, (const struct sockaddr*)&sin, sizeof(sin)) < 0){

return -1;

}

//数据传输

while(True){

//write/read

char buff[128] = {0};

printf("请输入一个字符串: ");

scanf("%s", buff);

//写向服务器

ssize_t write(int fd, const void *buf, size_t count);

write(ser_fd, buff, sizeof(buff));

}

你可能感兴趣的:(C语言服务器的搭建)