出处:csdn火木达人
伯克利套接字(Berkeley sockets),也称为BSD Socket。伯克利套接字的应用编程接口(API)是采用C语言的进程间通信的库,经常用在计算机网络间的通信。 BSD Socket的应用编程接口已经是网络套接字的事实上的抽象标准。大多数其他程序语言使用一种相似的编程接口。
BSD Socket作为一种API,允许不同主机或者同一个计算机上的不同进程之间的通信。它支持多种I/O设备和驱动,但是具体的实现是依赖操作系统的。这种接口对于TCP/IP是必不可少的,所以是互联网的基础技术之一。它最初是由加州伯克利大学为Unix系统开发出来的。所有现代的操作系统都都实现了伯克利套接字接口,因为它已经是连接互联网的标准接口了。
TCP协议
服务器端编程的步骤:
1. 加载套接字库,创建套接字socket();
2. 绑定套接字到一个IP地址和一个端口上bind();
3. 将套接字设置为监听模式等待连接请求listen();
4. 请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字accept();
5. 用返回的套接字和客户端进行通信send()/recv();
6. 关闭套接字,关闭加载的套接字库close()。
- #include <iostream>
- #include<sys/types.h>
- #include<cstdlib>
- #include<string.h>
- #include<string>
- #include<unistd.h>
- #include<netinet/in.h>
- #include<sys/socket.h>
- #include<netdb.h>
- #include<arpa/inet.h>
- using namespace std;
- int PROXY_PORT = 5000;
- #define MAXBUF 1024
- int main(int argc, const char * argv[])
- {
- int sockfd;
- int newsockfd;
- struct sockaddr_in server_address;
- struct sockaddr_in client_address;
- socklen_t clilen = sizeof( client_address);
- //1.创建套接字
- sockfd = socket( AF_INET , SOCK_STREAM , 0 );
- if(sockfd < 0){
- perror("can't establish socket");
- exit(1);
- }
- //填充ip地址和端口
- bzero( &(server_address) ,sizeof(server_address ));
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(PROXY_PORT);
- server_address.sin_addr.s_addr = INADDR_ANY;
- //2.绑定套接字到一个IP地址和一个端口上
- if(::bind( sockfd , (struct sockaddr *)&server_address , sizeof(struct sockaddr)) < 0)
- {
- perror("can't bind");
- exit(1);
- }
- //3. 将套接字设置为监听模式等待连接请求
- if(listen(sockfd ,5) < 0)
- {
- perror("cannot listen");
- exit(1);
- }
- //4.请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字
- newsockfd = accept( sockfd , (sockaddr *)&client_address , &clilen);
- printf("accept client %s\n; newsockfd: %d",inet_ntoa(server_address.sin_addr),newsockfd);
- //5. 用返回的套接字和客户端进行通信
- char sendMsg[256] = {0};
- sprintf(sendMsg, "%s","Welcome to my server\n");
- int len = (int)send(newsockfd,sendMsg,strlen(sendMsg),0);//发送数据
- char buffer[MAXBUF];
- bzero(buffer , MAXBUF);
- while((len = (int)recv(newsockfd, buffer, MAXBUF,0)) > 0)//接受数据
- {
- printf("%s\n",buffer);
- bzero(buffer, MAXBUF);
- sprintf(buffer, "%s","server data");
- if(send(newsockfd,buffer,len,0)<0)
- {
- perror("write");
- return 1;
- }
- bzero(buffer, MAXBUF);
- }
- //6.关闭套接字库
- close(newsockfd);
- close(sockfd);
- return 0;
- }
客户端编程的步骤:
1. 加载套接字库,创建套接字socket();
2. 向服务器发出连接请求connect();
3. 和服务器端进行通信send()/recv();
4. 关闭套接字,关闭加载的套接字库close()。
- #include <iostream>
- #include<sys/types.h>
- #include<cstdlib>
- #include<string.h>
- #include<string>
- #include<unistd.h>
- #include<netinet/in.h>
- #include<sys/socket.h>
- #include<netdb.h>
- #include<arpa/inet.h>
- #define PROXY "127.0.0.1" //your ip address
- int PROXY_PORT = 5000;
- #define MAXBUF 1024
- int main(int argc, const char * argv[])
- {
- int sockfd;
- struct sockaddr_in serv_addr;
- struct hostent* server;
- //套接字结构,包括远程的ip
- server = gethostbyname(PROXY);
- int iplen = 16;
- char* ip = (char*) malloc(iplen);
- inet_ntop( AF_INET , (void*) server->h_addr_list[0], ip ,iplen);
- bzero( (sockaddr_in *)&serv_addr , sizeof(sockaddr_in));
- serv_addr.sin_family = AF_INET;
- int ret;
- //1. 加载套接字库,创建套接字
- sockfd = socket ( AF_INET,SOCK_STREAM,0);
- bcopy( (char*)server->h_addr, (char*)& serv_addr.sin_addr.s_addr,server->h_length );
- serv_addr.sin_port = htons(PROXY_PORT);
- //2. 向服务器发出连接请求
- if((ret = connect(sockfd,(struct sockaddr*)& serv_addr, sizeof(serv_addr))) < 0){
- printf("Cannot connect to server");
- exit(0);
- }
- //3. 和服务器端进行通信
- char buffer[MAXBUF];
- int n;
- bzero(buffer, MAXBUF);
- printf("connected to server\n");
- int len= (int)recv(sockfd,buffer,BUFSIZ,0);//接收服务器端信息
- printf("server msg : %s \n",buffer); //打印服务器端信息
- while (1) {
- printf("input msg:\n");
- bzero(buffer , 1023);
- scanf("%[^\n]",buffer);
- getchar();
- int len = (int)strlen(buffer);
- if( len > 0){
- buffer[len] = '\n';
- buffer[len+1] = '\0';
- // n = write(sockfd , buffer , strlen(buffer));
- n = (int)send(sockfd, buffer, strlen(buffer), 0);
- if(n<0)break;
- }
- }
- //4. 关闭套接字
- close(sockfd);
- return 0;
- }
默认创建的是阻塞模式
UDP协议
服务器端不需要listen和accept
客户端不需要connect
服务器端和客户端收发数据使用recvfrom和sendto