名词:
1.套接字:IP+端口,套接口是端口
2.网络地址:在网络这张大网的唯一编号,IP地址,包含网络ID和主机ID,分为ABCDE类
ABC类网络ID长度分别为8位,16位,24位(IPv4)
A:0.0.0.0~127.255.255.255
B.128.0.0.0~191.255.255.255
C:192.0.0.0~223.255.255.255
D:224.0.0.0~239.255.255.255
E:240.0.0.0~247.255.255.255
最常用的是BC类
刚ping了一下百度220.181.38.150。C类
linux下socket编程主要为以下几个函数的运用:
socket():
socket就相当于声明传输格式
socket(PF_INET,SOCK_STREAM,0);
int socket( int af, int type, int protocol);(定义)
af:一个地址描述。仅支持AF_INET格式,也就是说ARPA Internet地址格式。
type:指定socket类型。新套接口的类型描述类型,如TCP(SOCK_STREAM)和UDP(SOCK_DGRAM)。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、SOCK_PACKET、SOCK_SEQPACKET等等。
protocol:顾名思义,就是指定协议。套接口所用的协议。如调用者不想指定,可用0。常用的协议有,IPPROTO_TCP、IPPROTO_UDP、IPPROTO_STCP、IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议。
返回值是套接字。
bind():
int bind( int sockfd , const struct sockaddr * my_addr, socklen_t addrlen);
sockfd 表示已经建立的套接字;
my_addr 是一个指向sockaddr结构体类型的指针;
addrlen表示my_addr结构的长度,可以用sizeof操作符获得。
listen():
int listen( int sockfd, int backlog);
sockfd:用于标识一个已捆绑未连接套接口的描述字。
backlog:等待连接队列的最大长度。
connect():
int connect(SOCKET s, const struct sockaddr * name, int namelen);
s:标识一个未连接socket
name:指向要连接套接字的sockaddr结构体的指针
namelen:sockaddr结构体的字节长度
accept():
SOCKET accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
sockfd:套接字描述符,该套接口在listen()后监听连接。
addr:(可选)指针,指向一缓冲区,其中接收为通讯层所知的连接实体的地址。Addr参数的实际格式由套接口创建时所产生的地址族确定。
addrlen:(可选)指针,输入参数,配合addr一起使用,指向存有addr地址长度的整型数。
recv():
int recv( In SOCKET s, Out char *buf, In int len, In int flags);
该函数的第一个参数指定接收端套接字描述符;
第二个参数指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
第三个参数指明buf的长度;
第四个参数一般置0。
recv(client_sockfd,buf,BUFSIZ,0);
send():
int send( SOCKET s, const char FAR *buf, int len, int flags );
(1)第一个参数指定发送端套接字描述符;
(2)第二个参数指明一个存放应用程序要发送数据的缓冲区;
(3)第三个参数指明实际要发送的数据的字节数;
(4)第四个参数一般置0。
close():
close(client_sockfd);
关闭套接字
代码如下:
server:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int server_sockfd;//服务器端套接字
int client_sockfd;//客户端套接字
int len;
struct sockaddr_in my_addr; //服务器网络地址结构体
struct sockaddr_in remote_addr; //客户端网络地址结构体
int sin_size;
char buf[BUFSIZ]; //数据传送的缓冲区
memset(&my_addr,0,sizeof(my_addr)); //清零
my_addr.sin_family=AF_INET; //设置为IP通信
my_addr.sin_addr.s_addr=INADDR_ANY;//允许连接到所有本地地址上
my_addr.sin_port=htons(8192); //服务器端口号
/*IPv4协议,TCP协议*/
if((server_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket error");
return -1;
}
/*将套接字绑定到服务器的网络地址上*/
if(bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
{
perror("bind error");
return -1;
}
/*监听队列长度为10*/
if(listen(server_sockfd,10)<0)
{
perror("listen error");
return -1;
};
sin_size=sizeof(struct sockaddr_in);
/*等待客户端连接请求到达*/
if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,(socklen_t*)&sin_size))<0)
{
perror("accept error");
return 1;
}
printf("accept client:%s\n",inet_ntoa(remote_addr.sin_addr));
len=send(client_sockfd,"Welcome to my server\n",21,0);//发送欢迎信息
/*接收客户端的数据并将其发送给客户端--recv返回接收到的字节数,send返回发送的字节数*/
while((len=recv(client_sockfd,buf,BUFSIZ,0))>0)
{
buf[len]='\0';
printf("%s\n",buf);
if(send(client_sockfd,buf,len,0)<0)
{
perror("write error");
return -1;
}
}
/*关闭套接字*/
close(client_sockfd);
close(server_sockfd);
return 0;
}
client端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <unistd.h>
int main(void)
{
int client_sockfd;
int len;
struct sockaddr_in remote_addr; //服务器端网络地址结构体
char buf[BUFSIZ]; //数据传送的缓冲区
memset(&remote_addr,0,sizeof(remote_addr)); //清零
remote_addr.sin_family=AF_INET; //设置为IP通信
remote_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP地址
remote_addr.sin_port=htons(8192); //服务器端口号
/*创建客户端套接字--IPv4协议,面向连接通信,TCP协议*/
if((client_sockfd=socket(PF_INET,SOCK_STREAM,0))<0)
{
perror("socket error");
return -1;
}
/*将套接字绑定到服务器的网络地址上*/
if(connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr))<0)
{
perror("connect error");
return -1;
}
printf("connected to server\n");
len=recv(client_sockfd,buf,BUFSIZ,0);//接收服务器端信息
buf[len]='/0';
printf("%s",buf); //打印服务器端信息
while(1)
{
printf("Enter string to send:");
scanf("%s",buf);
if(!strcmp(buf,"exit"))
break;
len=send(client_sockfd,buf,strlen(buf),0);
len=recv(client_sockfd,buf,BUFSIZ,0);
buf[len]='\0';
printf("received:%s\n",buf);
}
/*关闭套接字*/
close(client_sockfd);
return 0;
}