@Dubyoo
2014-06-13T12:47:20.000000Z
字数 4956
阅读 3156
服务端:socket -> bind -> listen -> accept -> recv -> send -> close客户端:socket ------------------> connect -> send -> recv -> close
/* socket:生成一个套接口描述符 */int socket(int domain, int type, int protocol);//domain ---> AF_INET: IPv4; AF_INET6: IPv6;//type ---> SOCK_STREAM: tcp; SOCK_DGRAM: udp;//protocol ---> 指定socket传输所用的协议编号,通常为0 。/*返回值:成功则返回套接口描述符,失败返回-1*/
/* bind:绑定一个端口号和ip地址,使套接口与端口号和ip地址相关联 */int bind(int sockfd, struct sockaddr * my_addr, int addrlen);// sockfd为前面socket的返回值。// my_addr为结构体指针变量,结构体如下// addrlen:sockaddr的结构体长度。通常是sizeof(struct sockaddr);/*返回值:成功则返回0,失败返回-1*/
/*结构体*/struct sockaddr //此结构体不常用{unsigned short int sa_family; //调用socket()时的domain参数,即AF_INET值。char sa_data[14]; //最多使用14个字符长度};//使用ipv4时,其socketaddr结构定义便为struct sockaddr_in //常用的结构体{unsigned short int sin_family; //即为sa_family AF_INETuint16_t sin_port; //为使用的port编号struct in_addr sin_addr; //为IP 地址unsigned char sin_zero[8]; //未使用};struct in_addr{uint32_t s_addr;};
/*bind实例*/struct sockaddr_in my_addr; //定义结构体变量memset(&my_addr, 0, sizeof(struct sockaddr)); //将结构体清空//或bzero(&my_addr, sizeof(struct sockaddr));my_addr.sin_family = AF_INET; //表示采用Ipv4网络协议my_addr.sin_port = htons(8888);//表示端口号为8888,通常是大于1024的一个值。//htons()用来将参数指定的16位hostshort转换成网络字符顺序my_addr.sin_addr.s_addr = inet_addr("192.168.1.13");// inet_addr()用来将IP地址字符串转换成网络所使用的二进制数字,如果为INADDR_ANY,这表示服务器自动填充本机IP地址。int iret = bind(sfd, (struct sockaddr*)&my_str, sizeof(struct socketaddr));if(iret == -1){perror("bind");close(sfd);exit(-1);}
注:
my_addr.sin_port 置为 0,函数会自动为你选择一个未占用的端口来使用。
my_addr.sin_addr.s_addr 置为 INADDR_ANY,系统会自动填入本机IP地址。
/* 使服务器的这个端口和IP处于监听状态,等待网络中某一客户机的连接请求。如果客户端有连接请求,端口就会接受这个连接 */int listen(int sockfd, int backlog);//sockfd: socket描述符//backlog: 指定同时能处理的最大连接要求,通常为10或者5。 最大值可设至128/*返回值:成功则返回0,失败返回-1*/
/*接受远程计算机的连接请求,建立起与客户机之间的通信连接*/int accept(int sockfd, struct sockaddr * addr, int * addrlen);//sockfd: socket描述符//addr: 系统会把远程客户端主机的信息(地址和端口号信息)保存到这个指针所指的结构体中//addrlen: 表示结构体的长度,为整型指针/*返回值:成功则返回新的客户端socket描述符new_fd,失败返回-1*/
/* 用新的套接字来接收远端主机传来的数据,并把数据存到由参数buf 指向的内存空间 */int recv(int sockfd,void *buf,int len,unsigned int flags);//sockfd: socket描述符//buf: 接收的字符串存入缓冲区buf中//len: 缓冲区长度//flags: 通常为0/*返回值:成功则返回实际接收到的字符数,可能会少于你所指定的接收长度。失败返回-1*/
/* 发送消息到指定IP */int send(int s,const void * msg,int len,unsigned int flags);//sockfd: socket描述符//msg: 一般为常量字符串,发出的消息//len: msg长度//flags: 通常为0/*返回值:成功则返回实际传送出去的字符数,可能会少于你所指定的发送长度。失败返回-1*/
close(sock_fd) ;
/*用来请求连接远程服务器,将参数sockfd 的socket 连至参数serv_addr 指定的服务器IP和端口号上去*/int connect(int sockfd,struct sockaddr * serv_addr,int addrlen);//sockfd: socket描述符//serv_addr: 结构体指针变量,存储着远程服务器的IP与端口号信息//addrlen: 结构体变量的长度/*返回值:成功则返回0,失败返回-1*/
/*connect实例*/struct sockaddr_in seraddr; //请求连接服务器memset(&seraddr, 0, sizeof(struct sockaddr));seraddr.sin_family = AF_INET;seraddr.sin_port = htons(8888); //服务器的端口号seraddr.sin_addr.s_addr = inet_addr("192.168.0.101"); //服务器的ipif(connect(sfd, (struct sockaddr*)&seraddr, sizeof(struct sockaddr)) == -1){perror("connect");close(sfd);exit(-1);}
/*tcp_server.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <sys/types.h>int main(int argc, char* argv[]) // ---> ./exe [port]{//1.socketint fd_server ,fd_client;if(-1 == (fd_server= socket(AF_INET,SOCK_STREAM, 0))){perror("socket");exit(-1);}//2.bindstruct sockaddr_in server_addr ;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET ;server_addr.sin_port = htons(atoi(argv[1]));server_addr.sin_addr.s_addr = INADDR_ANY ;if(0 != bind(fd_server, (struct sockaddr*)&server_addr, sizeof(server_addr))){perror("bind");close(fd_server);exit(-1);}//3.listenif(-1 == listen(fd_server, 5)){perror("listen");close(fd_server);exit(-1);}//acceptstruct sockaddr_in client_addr ;memset(&client_addr, 0, sizeof(client_addr));int len = sizeof(client_addr);fd_client = accept(fd_server, (struct sockaddr*)&client_addr, &len);printf("ip: %s:%d connection establited !\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port) );//4.recvchar buf[128] ;int iret = recv(fd_client, buf, 128, 0);buf[iret] = '\0';write(1, buf, strlen(buf));//5.sendmemset(buf, 0, 128);strcpy(buf, "I am the server, your msg has been received !\n");send(fd_client, buf, strlen(buf), 0);//6.closeclose(fd_server);close(fd_client);return 0 ;}
/*tcp_client.c*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <sys/types.h>int main(int argc, char * argv[]) // ---> ./exe [ip] [port]{//1.socketint fd_client ;fd_client = socket(AF_INET, SOCK_STREAM, 0);if(fd_client <= 0){perror("socket");exit(-1);}//2.connectstruct sockaddr_in server_addr ;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET ;server_addr.sin_port = htons(atoi(argv[2]));server_addr.sin_addr.s_addr = inet_addr(argv[1]);if(-1 == connect(fd_client, (struct sockaddr*)&server_addr, sizeof(server_addr))){perror("connect");close(fd_client);exit(-1);}//3.sendsend(fd_client, "Hello, I am the client !\n", 25, 0);//4.recvchar buf[128] ="";int iret = recv(fd_client, buf, 128, 0);buf[iret] = 0 ;write(1, buf, strlen(buf));close(fd_client);return 0 ;}