linux网络编程c++基础(socket)

名词:

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;
}


版权声明:本文为yangkaiandy原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。