一、服务器端的搭建Server:

1流程socket()--->struct sockaddr_in; ----->bind()------>listen() ---->accept()----->recv()/send()----->close();

2.编写服务器重点函数用法:

a. socket()
#include<sys/socket.h>
int socket(int family, int type, int protocol );

return: 成功返回非负描述符(也叫套接字描述符,简称sockfd),失败返回-1;

family 是协议族(AF_INET是Ipv4的协议,还有ipv6,unix);type是指明套接字类型(SOCK_STREAM,SOCK_DGRAM,流式套接字,数据报套接字);protocol 一般置0,选择所给定family和type组合的系统默认值.

绑定之前用地址结构填充套接字:

struct sockaddr_in addrSer,addrCli;
addSer.sin_family = AF_INET;
addSer.sin_port = htons(MY_PORT);//其中htons()将主机字节顺序转换成网络字节顺序的短整型,属于大端模式
addSer.sin_addr.s_addr =  inet_addr(IP_SER);//其中inet_addr()是将带小数点和十进制数转换成二进制以便计算机读取。
socklen_t len = sizeof(struct sockaddr_in);//返回socklen_t类型的len

inet_addr()头文件:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
b.bind()
 
#include<sys/socket.h>
int bind(int socket, const struct sockaddr address,socklen_t address_len);

return 成功0,失败返回-1;

第一个参数:套接字描述符,创建的套接字返回值。

第二个参数:const struct sockadr*address: 指向特定于协议的地址结构的指针,若定义的是struct sockaddr_in需要强制类型转换。

第三个参数:返回一个socklen_t类型的该地址结构的长度,(其中socklen_t可以等价short类型,struct sockaddr和struct sockaddr_in的长度都是16字节)。

c.listen()

listen函数使用主动连接套接字变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。

该函数把创建的时的socket<主动套接字>,当调用connect时候发起连接客户端套接字,listen把主动套接字变为被动套接字

#include <sys/types.h> 
#include <sys/socket.h>
int listen(int sockfd, int backlog);

return 成功返回0,失败返回-1;

第一个参数:套接字描述符,创建的套接字返回值。

第二个参数:监听套接字消息队列最大值(5~10)

d.accept()
#include <sys/socket.h>
int accept(int socket, struct sockaddr restrictaddress, socklen_t *restrict address_len);
return :成功返回非负套接字(既创建了新的套接字,返回一个全新的套接字描述符(已连接套接字描述符)),失败-1;
int )&addrCli,&len)

第一个参数:监听套接字由socket创建

第二个参数:指向cliaddr结构的指针,指向的是特定协议的地址结构的指针,由于返回类型是标准的地址结构的指 针所以,需要强制类型转换(struct sockaddr*)(注意这里指向的是客户端的地址结构指针)

第三个参数:指向len的指针,地址就是指针。

e.recv()/send()服务器一般先打开,等待客户端的连接,所以一般先接消息再发消息。

recv()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

第一个参数:是已连接套接字(即新的sockConn套接字描述符)。

第二个参数: buf的地址,由于数组名就是地址所以直接写出地址。

第三个地址: 一般0,默认的普通接受数据模式。

send()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

第一个参数:是已连接套接字(即新的sockConn套接字描述符)。

第二个参数: buf的地址,由于数组名就是地址所以直接写出地址。

第三个地址: 一般0,默认的普通发送数据模式。

char sendbuf[256];
char recvbuf[256];
while(1)
{ 
recv(sockConn,recvbuf,256,0);
printf("Cli : %s\n",recvbuf);
printf("Ser : ");
scanf("%d",sendbuf);要发的消息不能加\n;
if(strcmp(sendbuf, "quit") == 0)
break;
sendbuf(sockConn, sendbuf,strlen(sendbuf)+1,0);
}

总结:recv(),send() 函数,要是先接受就要先写recv()函数,,下一行用printf函数输出接收函数的字符串,

要是send()函数,发送函数,先布置好格式,用scanf()函数输入发送的字符串,最后在调用send(即可

发送字符串。

recv();接受函数先接再写,用printf("%s\n",recvbuf)函数加\n输出,可以一句输出结束。

send();发送函数先写再发,用scanf("%s",sendbuf)函数不加\n输入,分多句完成。

 

f.close()
#include <unistd.h>
int close(int fd);

头文件:

1 #include<stdio.h>
2 #include<unistd.h>
3 #include<sys/socket.h>
4 #include<stdlib.h>
5 #include<string.h>
6 #include<netinet/in.h>
7 #include<arpa/inet.h>
8 
9 #define MY_PORT 9080
10 #define IP_ADDR "127.0.0.1"
11 #define LISTEN_QUENE_SIZE 5
12 #define MAX_BUFFER_SIZE 256

搭建服务器代码:

1 #include"utitl.h"
2 //Server()
3 int main()
4 {
5 //socket()
6 int sockSer = socket(AF_INET, SOCK_STREAM, 0);
7 if(sockSer == -1)
8 {
9 perror("Ser socket");
10 exit(1);
11 }
12 struct sockaddr_in addrSer,addrCli;
13 addrSer.sin_family = AF_INET;
14 addrSer.sin_port = htons(MY_PORT);
15 addrSer.sin_addr.s_addr = inet_addr(IP_ADDR);
16 //bind()
17 int len = sizeof(struct sockaddr_in);
18 int Bind_Ser = bind(sockSer, (struct sockaddr*)&addrSer, len);
19 if (Bind_Ser == -1)
20 {
21 perror("Ser bind");
22 exit (1);
23 }
24 //listen()
25 int Listen_Ser = listen(sockSer,LISTEN_QUENE_SIZE);
26 if(Listen_Ser == -1)
27 {
28 perror("Ser listen");
29 exit(1);
30 }
31 //accept()
32 int sockConn = accept(sockSer, (struct sockaddr*)&addrCli,&len);
33 if(sockConn == -1)
 
 
 34         {
 35             printf("Server accept client is failuer.\n");
 36             close(sockSer);
 37             exit(1);
 38         }
 39         else
 40         {
 41             printf("Server accept client is ok.\n");
 42         }
 43     char sendbuf[MAX_BUFFER_SIZE];
 44     char recvbuf[MAX_BUFFER_SIZE];
 45    //recv(), send()
 46     while (1)
 47     {
 48         recv(sockConn,recvbuf,MAX_BUFFER_SIZE,0);
 49         printf("Cli : >%s\n",recvbuf);
 50         printf("Ser : >");
 51         scanf("%s",sendbuf);
 52         if(strcmp(sendbuf,"quit") == 0)
 53             break;
 54         send(sockConn,sendbuf,strlen(sendbuf)+1,0);
 55     }
 56     close(sockSer);
 57     return 0;
 58 }

            

1.流程 socket()--->struct sockaddr_in(addrSer)(bind())--->connect()---->send()/recv()---->close();

2.编写客户端函数重点:

注意:客户端可以不绑定套接字,listen()函数是服务器特有函数函数。

connect()创建的第二个参数需要服务器的地址结构,所以要构建服务器的地址结构addrSer,第三个参数求的是地址 结构的长度。

3.connect()
#include <sys/types.h> 
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

第一个参数:是客户端套接字描述符sockCli

第二个参数: 是指向特定的协议地址结构指针&addrSer

第三个参数:返回值为socklen_t的地址结构长度。

return :成功返回0.失败-1

服务器代码:

1 #include"utitl.h" 
2 //Client
3 int main()
4 {
5 //socket()
6 int sockCli = socket(AF_INET, SOCK_STREAM, 0);
7 if(sockCli == -1)
8 {
9 perror("Cli socket");
10 exit(1);
11 }
12 struct sockaddr_in addrSer;
13 addrSer.sin_family = AF_INET;
14 addrSer.sin_port = htons(MY_PORT);
15 addrSer.sin_addr.s_addr = inet_addr(IP_ADDR);
16 socklen_t len = sizeof( struct sockaddr );
17 //connect()
18 int sockConn = connect(sockCli, (struct sockaddr *)&addrSer, len);
19 if(sockConn == -1)
20 {
21 printf("Client connect server is failuer .\n");
22 close(sockCli);
23 exit(1);
24 }
25 else
26 {
27 printf("Client connect server is ok.\n");
28 
29 }
30 char sendbuf[MAX_BUFFER_SIZE];
31 char recvbuf[MAX_BUFFER_SIZE];
32 // send(), recv();
33 while(1)
 34     {
 35         printf("Cli : >");
 36         scanf("%s",sendbuf);
 37         if(strcmp(sendbuf,"quit") == 0)
 38             break;
 39         send(sockCli,sendbuf,strlen(sendbuf)+1,0);
 40        
 41         recv(sockCli,recvbuf,MAX_BUFFER_SIZE,0);
 42         printf("Ser : >%s\n",recvbuf);
 43     }
 44     close(sockCli);
 45 
 46     return 0;
 47 }