Socket分为三种:
1. SOCK_STREAM TCP
2. SOCK_DGRAM UDP
3. SOCK_RAW 基于IP协议,用于新的网络协议的测试。
常用结构体:
Struct sockaddr
{
U_shortsa_family;//协议族,AF_XXXX
Charsa_data[14]; //14字节的特定协议地址。
}
等价于上述结构体的是sockaddr_in比较常用这个结构体
Struct sockaddr_in
{
Shortsin_family;
Unsignedshort int sin_port;
Structin_addr sin_addr; //
Unsignedchar sin_zero[8]; //
}
Typedef struct in_addr
{
Union{
Struct
{
Unsigned char s_b1,
S_b2,
S_b3,
S_b4;
}S_un_b;
Struct{
Unsignedshort s_w1,
S_w2;
}s_un_w;
Unsigned long s_addr;
}s_un
}IN_ADDR
由于大小端的缘故,提供几个函数进行转换
Htons short 型转换 host to network
Htonl long 型转换 host to network
Ntohs short 型转换network to host
Ntohl long 型转换 network to host
TCP 程序设计:
server:
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #define MAX_CONN_NUM (20)
- #define PORT_NUM (2000)
- int main(int argc, char **argv)
- {
- int ret = 0;
- int sock_fd, new_fd;
- struct sockaddr_in server_addr, client_addr;
- int sock_in_size;
- int n_bytes;
- char buf[512];
- /* 1 create socket */
- sock_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == sock_fd) {
- fprintf(stdout, "create sock err = %s\n", strerror(errno));
- exit(1);
- }
- /*set default val*/
- bzero(&server_addr, sizeof(struct sockaddr_in));
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
- server_addr.sin_port = htons(PORT_NUM);
- /*2 bind socket*/
- if (bind(sock_fd,
- (struct sockaddr *)(&server_addr),
- sizeof(struct sockaddr)) == -1) {
- fprintf(stdout, "bind error = %s\n",strerror(errno));
- exit(1);
- }
- /*3 listen*/
- if(listen(sock_fd, MAX_CONN_NUM) == -1) {
- fprintf(stdout, "listen error = %s\n", strerror(errno));
- exit(1);
- }
- /**/
- while(1) {
- /*4 accept */
- sock_in_size = sizeof(struct sockaddr_in);
- new_fd = accept(sock_fd,
- (struct sockaddr *)(&client_addr),
- &sock_in_size);
- if (-1 == new_fd) {
- fprintf(stdout, "accept error : %s\n", strerror(errno));
- exit(1);
- }
- // fprintf(stdout, "connection from : %s\n", inet_ntoa(client_addr.sin_addr));//inet_ntoa 函数在ubuntu上用不了,用inet_ntop
- fprintf(stdout, "connection from : \n");
- /*5 read/write */
- n_bytes = read(new_fd, buf, 512);
- if (-1 == n_bytes) {
- fprintf(stdout,"read error : %s\n", strerror(errno));
- exit(1);
- }
- buf[n_bytes] = '\0';
- fprintf(stdout,"client:%s\n", buf);
- close(new_fd);
- }
- /*close socket*/
- close(sock_fd);
- exit(0);
- return ret;
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <netdb.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <sys/socket.h>
- #define MAX_CONN_NUM (20)
- #define PORT_NUM (2000)
- int main(int argc, char **argv)
- {
- int ret = 0;
- int sock_fd;
- struct sockaddr_in server_addr;
- char buf[512];
- struct hostent *host;
- if (argc != 2) {
- fprintf(stderr, "input server hostname\n");
- exit(1);
- }
- host = gethostbyname(argv[1]);
- if (NULL == host) {
- fprintf(stderr,"get hostname error\n");
- exit(1);
- }
- /* 1 create socket */
- sock_fd = socket(AF_INET, SOCK_STREAM, 0);
- if (-1 == sock_fd) {
- fprintf(stderr, "create sock err = %s\n", strerror(errno));
- exit(1);
- }
- /*set default val*/
- bzero(&server_addr, sizeof(struct sockaddr_in));
- server_addr.sin_family = AF_INET;
- server_addr.sin_addr = *((struct in_addr *)host->h_addr);
- server_addr.sin_port = htons(PORT_NUM);
- /*2 connect socket*/
- if(-1 == connect(sock_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))) {
- fprintf(stderr, "connect error = %s\n",strerror(errno));
- exit(1);
- }
- /*3 read/write */
- printf("please input:\n");
- fgets(buf, 512, stdin);
- write(sock_fd, buf, strlen(buf));
- /*4 close socket*/
- close(sock_fd);
- exit(0);
- return ret;
- }