1)第一个就是头文件的添加
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
大体上面几个头文件就可以完成一次基本的客户端服务器交互了。具体每个头文件的重要还不是很清晰,但是可以通过查询得知。
特别就是<errno.h>中的错误处理函数 挺好用的 但是还是要不是很了解。。
2)数据类型
struct sockaddr
{
unsigned short sa_family; //地址族, 一般为AF_INET
char sa_data[14]; //14字节的协议地址
}
struct sockaddr_in
{
short int sin_family; //地址族
unsigned short int sin_port; //端口号
struct in_addr in_addr; //ip地址
unsigned char sin_zero[8]; //填充
}
通常所定义 sockaddr_in 然后再转换成sockaddr进行地址传输
几个函数
·htonl():把32位值从主机字节序转换成网络字节序
·htons():把16位值从主机字节序转换成网络字节序
·ntohl():把32位值从网络字节序转换成主机字节序
·ntohs():把16位值从网络字节序转换成主机字节序
至于ip地址转换
inet_addr("127.0.0.1");
还有一个就是通过主机地址来解析的
gethostbyname 具体怎么用 可以去查下
然后自己感觉 ip转换函数都是在
inet_XX后面的。。。
典型的定义本机地址。。。
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(8000);
//my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
my_addr.sin_addr.s_addr=INADDR_ANY;
3)常用函数
1 socket()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int socket(int domain, int type, int protocol)
domain: 协议类型,一般为AF_INET
type: socket类型
protocol:用来指定socket所使用的传输协议编号,通常设为0即可
注释:
(1)常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的 Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用
(2)协议类型 AF_INET PF_INET 貌似没有什么区别
AF 表示ADDRESS FAMILY就是地址族
PF 表示PROTOCL FAMILY就是协议族
2 bind()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
sockfd: socket描述符
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
addrlen:常被设为sizeof(struct sockaddr)
注释:
更加普遍的使用方式是:
int socketID;
struct sockaddr_in my_addr;
//...
bind(socketID,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));
3 connect()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
sockfd: 目的服务器的socket描述符
serv_addr:包含目的机器ip地址和端口号的指针
addrlen:sizeof(struct sockaddr)
注释:
貌似addrlen 可以用 socklen_t 类型。但是用int 也是没有问题的
4 listen()
头文件:
#include <sys/socket.h>
函数原型:
int listen(int sockfd, int backlog);
sockfd:socket()系统调用返回的socket描述符
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
5 accept()
头文件:
#include <sys/types.h>
#inlcude <sys/socket.h>
函数原型:
int accept(int sockfd, void *addr, int addrlen)
sockfd:是被监听的socket描述符
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
addrlen:sizeof(struct sockaddr_in)
注释:
这里我觉得很有问题,因为我在编译的时候使用的下面的构造
struct sockaddr_in client_addr;
socklen_t size=sizeof(struct sockaddr);
client=accept(socketID,(struct sockaddr*)&client_addr,&size);
而使用上面的构造的时候:
编译的时候就会出错。。。
6 send()
头文件:
#include <sys/socket.h>
函数原型:
int send(int sockfd, const void *msg, int len, int flags);
sockfd:用来传输数据的socket描述符
msg:要发送数据的指针
flags: 0
7 recv()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int recv(int sockfd, void *buf, int len, unsigned int flags)
sockfd:接收数据的socket描述符
buf:存放数据的缓冲区
len:缓冲的长度
flags:0
8 sendto()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
9 recvfrom()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
10 read() write()
int read(int fd, char *buf, int len)
int write(int fd, char *buf, int len)
11 shutdown()
close(sockfd)
int shutdown(int sockfd, int how)
4)代码
服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
struct sockaddr_in my_addr;
int socketID=socket(AF_INET,SOCK_STREAM,0);
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(8000);
//my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
my_addr.sin_addr.s_addr=INADDR_ANY;
bind(socketID,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr));
printf("Wait For being connected!"n");
int client;
listen(socketID,20);
struct sockaddr_in client_addr;
socklen_t size=sizeof(struct sockaddr);
client=accept(socketID,(struct sockaddr*)&client_addr,&size);
printf("ONE Connect!"n");
char *msg="Hello";
int len =strlen(msg);
printf("%d"n",len);
int suc=send(client,msg,len,0);
if(suc<0)
printf("MSG send error!,Error Marker is %d, Error msg is%s "n",errno,strerror(errno));
else
printf("MSG Send"n");
return 0;
}
客户端:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main()
{
struct sockaddr_in server_addr;
int socketID;
socketID=socket(AF_INET,SOCK_STREAM,0);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(8000);
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
int size=sizeof(struct sockaddr);
if(connect(socketID,(struct sockaddr*)&server_addr,size)<0)
printf("Connetct error!"n");
else
printf("Connect successed!"n");
char msg[30];
recv(socketID,msg,30,0);
int msgLen=strlen(msg);
printf("%d"n",msgLen);
printf("%s"n",msg);
char ss[]="1230faflg";
if(send(socketID,ss,10,0)<0) printf("Send Error!"n");
return 0;
}
代码实现的功能很少,主要就是测试一下linux下的网络连接函数怎么用才行。
模型都是很简单的 但是用起来是需要功力的
PS:大部分的内容都是来源网络,最近才开始使用linux平台。整理了下内容,加深下自己的理解。
#include <errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
大体上面几个头文件就可以完成一次基本的客户端服务器交互了。具体每个头文件的重要还不是很清晰,但是可以通过查询得知。
特别就是<errno.h>中的错误处理函数 挺好用的 但是还是要不是很了解。。
2)数据类型
struct sockaddr
{
unsigned short sa_family; //地址族, 一般为AF_INET
char sa_data[14]; //14字节的协议地址
}
struct sockaddr_in
{
short int sin_family; //地址族
unsigned short int sin_port; //端口号
struct in_addr in_addr; //ip地址
unsigned char sin_zero[8]; //填充
}
通常所定义 sockaddr_in 然后再转换成sockaddr进行地址传输
几个函数
·htonl():把32位值从主机字节序转换成网络字节序
·htons():把16位值从主机字节序转换成网络字节序
·ntohl():把32位值从网络字节序转换成主机字节序
·ntohs():把16位值从网络字节序转换成主机字节序
至于ip地址转换
inet_addr("127.0.0.1");
还有一个就是通过主机地址来解析的
gethostbyname 具体怎么用 可以去查下
然后自己感觉 ip转换函数都是在
inet_XX后面的。。。
典型的定义本机地址。。。
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(8000);
//my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
my_addr.sin_addr.s_addr=INADDR_ANY;
3)常用函数
1 socket()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int socket(int domain, int type, int protocol)
domain: 协议类型,一般为AF_INET
type: socket类型
protocol:用来指定socket所使用的传输协议编号,通常设为0即可
注释:
(1)常用的Socket类型有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的 Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用
(2)协议类型 AF_INET PF_INET 貌似没有什么区别
AF 表示ADDRESS FAMILY就是地址族
PF 表示PROTOCL FAMILY就是协议族
2 bind()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)
sockfd: socket描述符
my_addr:是一个指向包含有本机ip地址和端口号等信息的sockaddr类型的指针
addrlen:常被设为sizeof(struct sockaddr)
注释:
更加普遍的使用方式是:
int socketID;
struct sockaddr_in my_addr;
//...
bind(socketID,(struct sockaddr*)&my_addr,sizeof(struct sockaddr));
3 connect()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
sockfd: 目的服务器的socket描述符
serv_addr:包含目的机器ip地址和端口号的指针
addrlen:sizeof(struct sockaddr)
注释:
貌似addrlen 可以用 socklen_t 类型。但是用int 也是没有问题的
4 listen()
头文件:
#include <sys/socket.h>
函数原型:
int listen(int sockfd, int backlog);
sockfd:socket()系统调用返回的socket描述符
backlog:指定在请求队列中的最大请求数,进入的连接请求将在队列中等待accept()它们。
5 accept()
头文件:
#include <sys/types.h>
#inlcude <sys/socket.h>
函数原型:
int accept(int sockfd, void *addr, int addrlen)
sockfd:是被监听的socket描述符
addr:通常是一个指向sockaddr_in变量的指针,该变量用来存放提出连接请求服务的主机的信息
addrlen:sizeof(struct sockaddr_in)
注释:
这里我觉得很有问题,因为我在编译的时候使用的下面的构造
struct sockaddr_in client_addr;
socklen_t size=sizeof(struct sockaddr);
client=accept(socketID,(struct sockaddr*)&client_addr,&size);
而使用上面的构造的时候:
编译的时候就会出错。。。
6 send()
头文件:
#include <sys/socket.h>
函数原型:
int send(int sockfd, const void *msg, int len, int flags);
sockfd:用来传输数据的socket描述符
msg:要发送数据的指针
flags: 0
7 recv()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int recv(int sockfd, void *buf, int len, unsigned int flags)
sockfd:接收数据的socket描述符
buf:存放数据的缓冲区
len:缓冲的长度
flags:0
8 sendto()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int sendto(int sockfd, const void *msg, int len, unsigned int flags, const struct sockaddr *to, int tolen);
9 recvfrom()
头文件:
#include <sys/types.h>
#include <sys/socket.h>
函数原型:
int recvfrom(int sockfd, void *buf, int len, unsigned int flags, struct sockaddr *from, int fromlen)
10 read() write()
int read(int fd, char *buf, int len)
int write(int fd, char *buf, int len)
11 shutdown()
close(sockfd)
int shutdown(int sockfd, int how)
4)代码
服务器端:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
int main()
{
struct sockaddr_in my_addr;
int socketID=socket(AF_INET,SOCK_STREAM,0);
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(8000);
//my_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
my_addr.sin_addr.s_addr=INADDR_ANY;
bind(socketID,(struct sockaddr*)(&my_addr),sizeof(struct sockaddr));
printf("Wait For being connected!"n");
int client;
listen(socketID,20);
struct sockaddr_in client_addr;
socklen_t size=sizeof(struct sockaddr);
client=accept(socketID,(struct sockaddr*)&client_addr,&size);
printf("ONE Connect!"n");
char *msg="Hello";
int len =strlen(msg);
printf("%d"n",len);
int suc=send(client,msg,len,0);
if(suc<0)
printf("MSG send error!,Error Marker is %d, Error msg is%s "n",errno,strerror(errno));
else
printf("MSG Send"n");
return 0;
}
客户端:
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main()
{
struct sockaddr_in server_addr;
int socketID;
socketID=socket(AF_INET,SOCK_STREAM,0);
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(8000);
server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
int size=sizeof(struct sockaddr);
if(connect(socketID,(struct sockaddr*)&server_addr,size)<0)
printf("Connetct error!"n");
else
printf("Connect successed!"n");
char msg[30];
recv(socketID,msg,30,0);
int msgLen=strlen(msg);
printf("%d"n",msgLen);
printf("%s"n",msg);
char ss[]="1230faflg";
if(send(socketID,ss,10,0)<0) printf("Send Error!"n");
return 0;
}
代码实现的功能很少,主要就是测试一下linux下的网络连接函数怎么用才行。
模型都是很简单的 但是用起来是需要功力的
PS:大部分的内容都是来源网络,最近才开始使用linux平台。整理了下内容,加深下自己的理解。