Linux网络编程二、tcp连接API
一、服务端 1、创建套接字: int socket(int domain,int type,int protocol); domain:指定协议族,通常选用AF_INET。 type:指定socket类型,TCP通信下使用SOCK_STREAM。 protocol:指定协议,通常为0。 返回值:成功则返回新socket的文件描述符,失败返回-1。 头文件:sys/socket.h? ? ?sys/types.h 2、绑定套接字 int bind(int sockfd,struct sockaddr *my_addr,socklen_t addrlen); sockfd:要绑定的套接字。 my_addr:本地地址,使用sockaddr_in结构体创建。 addrlen:my_addr的长度。 返回值:成功返回0,失败返回-1。 3、监听套接字 int listen(int s,int backlog); s:要监听的套接字 backlog:指定未完成连接队列的最大长度,如果一个连接请求到达时为完成连接队列已满,那么客户端将会接收到错误。 返回值:成功返回0,失败返回-1。 4、接受连接 int accept(int s,struct sockaddr *addr,socklen_t *addrlen); s:接收连接请求的套接字。 addr:获取客户端信息。 addrlen:addr的长度。 返回值:成功返回一个非负整数表示的连接套接字,失败返回-1。 5、读取数据 ssize_t read(int fd,void *buf,size_t count); fd:文件描述符。 buf:缓冲区,读取的数据放在缓冲区中。 count:缓冲区大小。 返回值:成功返回读取到的字节数,失败返回-1。 注:read会阻塞。 ssize_t recv(int sockfd,size_t len,int flags); flags:一般设置为0。 其余同上 6、写数据 ssize_t write(int fd,const void *buf,size_t count); 同上。 int send(int s,const void *msg,int flags); 同上。 7、关闭套接字 int close(int fd); fd:要关闭的套接字。 返回值:成功返回0,失败返回-1。 8、其他 将本地编码转为网络编码 #include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort); 将网络编码转为本地 const char *inet_ntop(int af,const void *src,char *dst,socklen_t size); af:协议族。 src:原数据。 dst:缓冲区。 size:缓冲区大小。 返回值:成功返回转换后的字符串,失败返回NULL。 ? //tcp_server.c #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <arpa/inet.h> #include <ctype.h> #include <unistd.h> #include <stdlib.h> int main() { const int lfd=socket(AF_INET,SOCK_STREAM,0); if(lfd==-1) { perror("socket error"); exit(1); } struct sockaddr_in server; memset(&server,0,sizeof(server)); server.sin_family=AF_INET; server.sin_port=htons(8888); server.sin_addr.s_addr=htonl(INADDR_ANY); //设置端口复用 int flag=1; setsockopt(lfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag)); int ret=bind(lfd,(struct sockaddr*)&server,sizeof(server)); if(-1==ret) { perror("bind error"); exit(1); } ret=listen(lfd,20); if(ret==-1) { perror("listen error"); exit(1); } struct sockaddr_in client; socklen_t len=sizeof(client); int cfd =accept(lfd,(struct sockaddr*)&client,&len); if(cfd==-1) { perror("accept error"); exit(1); } printf("accept successful !!!n"); char ipbuf[64]={0}; printf("client IP: %s,port: %dn",inet_ntop(AF_INET,&client.sin_addr.s_addr,ipbuf,sizeof(ipbuf)),ntohs(client.sin_port)); while(1) { char buf[1024]={0}; int len=read(cfd,buf,sizeof(buf)); if(len==-1) { perror("read error"); exit(1); } else if(len==0) { close(cfd); break; } else { printf("recv buf: %sn",buf); for(int i=0;i<len;++i) { buf[i]=toupper(buf[i]); } printf("send buf: %sn",buf); write(cfd,len); } } close(cfd); close(lfd); return 0; } ? 二、客户端 1、创建套接字 int socket(int domain,int protocol); 2、连接客户端 int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen); sockfd:客户端创建的套接字。 addr:配置的要连接的服务器。 addrlen:addr的长度。 返回值:成功返回0,失败-1。 3、通信 同服务端,略。 ?tcp_client.c: 1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 #include <sys/stat.h> 6 #include <string.h> 7 #include <sys/socket.h> 8 #include <arpa/inet.h> 9 int main(int argc,char *argv[]) 10 { 11 int lfd=socket(AF_INET,0); 12 int port=atoi(argv[1]); 13 struct sockaddr_in serv; 14 serv.sin_family=AF_INET; 15 serv.sin_port=htons(port); 16 inet_pton(AF_INET,"127.0.0.1",&serv.sin_addr.s_addr); 17 connect(lfd,(struct sockaddr*)&serv,sizeof(serv)); 18 while(1) 19 { 20 char buf[1024]; 21 fgets(buf,sizeof(buf),stdin); 22 write(lfd,strlen(buf)); 23 memset(buf,sizeof(buf)); 24 int len=read(lfd,sizeof(buf)); 25 if(len==-1) 26 { 27 perror("read err"); 28 return -1; 29 } 30 else if(len==0) 31 { 32 break; 33 } 34 else 35 { 36 write(STDOUT_FILENO,len); 37 } 38 } 39 close(lfd); 40 return 0; 41 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |