1、什麼是socket套接字
 socket分為三種類型:
字節流套接字(Stream Socket),最常用socket類型,TCP協議使用此類接口。提供面向連接(建立虛擬電路)、無差錯、發送順序一致、無記錄邊界和非重復的網絡信包傳輸
數據報套接字(Datagram Socket),UDP協議使用此類接口,提供無連接服務,它以獨立的信包進行網絡傳輸,信包最大長度為32KB,傳輸不保證順序性、可靠性和無重復性,它通常用於單個報文傳輸或可靠性不重復的場合。數據報套接字接口的一個重要特點是它保留了記錄邊界。
原始數據報套接字(Raw Socket),提供對網絡下層通訊協議(eg:IP協議)的直接訪問,一般不是提供給普通用戶的,主要用於開發新的協議或者用於提取協議教隱蔽的功能
2、 客戶服務器通信流程
#include <
sys/types.h
> /* See NOTES */
#include <
sys/socket.h
>
int socket(int domain, int type, int protocol);//返回sockfd
函數定義:這個函數返回套接字描述符,它唯一標識一個socket,後續操作用它作為參數來進行一些讀寫操作,socket函數的三個參數分別為:
返回值:創建新描述符正確返回0,錯誤返回-1,並有對應的errorno詳情見 https://linux.die.net/man/2/socket
#include <sys/types.h>
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr,
socklen_t addrlen);
返回值:創建新描述符正確返回0,錯誤返回-1,詳情見 https://linux.die.net/man/2/bind
#include <sys/types.h>
#include <sys/socket.h>
int listen(int sockfd, int backlog);
返回值:創建新描述符正確返回0,錯誤返回-1,詳情見 https://linux.die.net/man/2/listen
#include <sys/types.h>
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
返回值:成功則返回一個非負的SOCKET類型的值,表示接收到的套接字描述符,錯誤返回-1,並有對應的errorno,詳情見https://linux.die.net/man/2/accept
3、C 程序
#include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <sys/types.h> #include <stdint.h> #include <netinet/in.h> #include <arpa/inet.h> #include <error.h> #include <errno.h> #include <unistd.h> #include <sys/time.h> int main(){ struct sockaddr_in server_addr, client_addr; int socketserver; int err; int socketclient;as struct timeval timeout; char rcvbuf[100]; char sedbuf[100000]; timeout.tv_sec=5; timeout.tv_usec=0; //socket buff size int opt=100000; if((socketserver = socket(AF_INET,SOCK_STREAM,0)) == -1) return 1; //接受時限5s //setsockopt(socketserver, SOL_SOCKET,SO_RCVTIMEO, (char*)&timeout,sizeof(timeout)); //發送時限5s //setsockopt(socketserver, SOL_SOCKET,SO_SNDTIMEO, (char*)&timeout,sizeof(timeout)); //接收緩沖區 setsockopt(socketserver, SOL_SOCKET, SO_RCVBUF, (const char*)&opt,sizeof(opt)); //發送緩沖區 setsockopt(socketserver, SOL_SOCKET, SO_SNDBUF, (const char*)&opt,sizeof(opt)); //設置服務器地址信息設置 server_addr.sin_family = AF_INET; //TCP server_addr.sin_port = htons(8080); //網絡字節順序采用大端模式 server_addr.sin_addr.s_addr = INADDR_ANY; //本地IP地址 // server_addr.sin_addr.s_addr=htonl(127.0.0.1); printf("server port:%ld\n", ntohs(server_addr.sin_port)); memset(server_addr.sin_zero,'\0',sizeof(server_addr.sin_zero)); err=bind(socketserver, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)); if(err == -1){ perror("bind error:"); return 1; } if((err = listen(socketserver,10)) == -1){ perror("listen error:"); return 1; } while(1){ int len = sizeof(struct sockaddr); head: if((socketclient = accept(socketserver,(struct sockaddr *)&client_addr,&len)) == -1){ if(errno == 11){ puts("timeout"); goto head; } else{ perror("accpet error:"); return 1; } } write(socketclient,sedbuf,100000); printf("send sucess\n"); // handle the connection of client while(1){ memset(rcvbuf,'\0',100); len = read(socketclient,rcvbuf,40); if(len <=0){ if(errno == EINTR || errno == EAGAIN)// except interruption XXX 92 continue; else{ perror("client down:"); break; } } printf(" I received %s\n",rcvbuf); }//while(1) handle the connection of client }//while(1) return 0; }View Code
http://www.bkjia.com/Linuxjc/1196046.htmlwww.bkjia.comtruehttp://www.bkjia.com/Linuxjc/1196046.html