socket TCP

来源:互联网 发布:js完善当当购物车页面 编辑:程序博客网 时间:2024/05/12 15:27

struct sockaddr_in include/linux/in.h

struct sockaddr_in {

  sa_family_t sin_family; //地址家族,“AF_XXX”,AF_INET,代表TCP/IP协议族

  __be16 sin_port; //存储端口号(使用网络字节顺序)

  struct in_addr sin_addr;//存储IP地址

  /* Pad to size of `struct sockaddr'. */

  unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) -

sizeof(unsigned short int) - sizeof(struct in_addr)];

};

include/linux/inet.h

#define INET_ADDRSTRLEN (16)

/* Address to accept any incoming messages. */

#define INADDR_ANY ((unsigned long int) 0x00000000)

sockaddr_in中的成员struct in_addr sin_addr表示32位的IP地址,但是我们通常用点分十进制字符串表示IP地址,以下函数可以在字符串表示和in_addr表示之间转换

字符串转in_addr的函数

#include <arpa/inet.h>

 int inet_aton(const char *cp, struct in_addr *inp);

 in_addr_t inet_addr(const char *cp);

in_addr转字符串函数

#include <arpa/inet.h>

 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

printf("received from [%s] at PORT [%d] \n", inet_ntop(AF_INET,&cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port));

/***TCP server*从客户端读字符,然后将每个字符转换为大写并回送给客户端*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#define MAXLINE 80#define SERV_PORT 8000int main(void){struct sockaddr_in servaddr, cliaddr;socklen_t cliaddr_len;int listenfd, connfd;char buf[MAXLINE];char str[INET_ADDRSTRLEN];int i, n;/***socket()打开一个网络通讯端口,成功则返回一个文件描述符*@AF_INET:IPv4 family参数指定为AF_INET*@SOCK_STREAM: TCP协议为SOCK_STREAM,UDP协议为SOCK_DGRAM*@0:表示IP*/listenfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//宏INADDR_ANY表示本地的任意IP地址servaddr.sin_port = htons(SERV_PORT);/***bind()绑定一个固定的网络地址和端口号,成功返回0,失败返回-1*listenfd这个用于网络通讯的文件描述符监听servaddr所描述的地址和端口*/bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));/***listen()声明listenfd处理监听状态,多个客户端发起连接,最多允许*20个客户端处于连接待状态,如果接收到更多的连接请求就忽略*/listen(listenfd, 20);printf("Accepting connections ...\n");//while死循环,每次循环处理一个客户端连接//cliaddr是传入传出参数,每次调用accept()之前应该重新赋值while (1) {cliaddr_len = sizeof(cliaddr);/***三次握手后,服务器调用accept()接受连接*如果服务咕咕调用accept()时还没有客户端的连接请求*就阻塞等待直到有客户端连接*@cliaddr:传出参数,accept()返回时传出客户端的地址和端口号*如果cliaddr参数为NULL,表示不关心客户端的地址*/connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);n = read(connfd, buf, MAXLINE);printf("received from [%s] at PORT [%d] \n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));                                                                                printf("%s \n", buf);for (i = 0; i< n; i++)buf[i] = toupper(buf[i]);write(connfd, buf, n);close(connfd);}}

/***client TCP*从命令行参数中获得一个字符串发给服务器,然后接收服务器*返回的字符串并打印*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#define MAXLINE 80#define SERV_PORT 8000int main(int argc, char **argv){struct sockaddr_in servaddr;char buf[MAXLINE];int sockfd, n;char *str;if (argc != 2) {fputs("usage: ./client message\n", stderr);exit(1);}str = argv[1];/***客户端不需要固定的端口号,因此不调用bind()*/sockfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&servaddr, sizeof(servaddr));servaddr.sin_family = AF_INET;inet_pton(AF_INET, "10.50.25.10", &servaddr.sin_addr);servaddr.sin_port = htons(SERV_PORT);/***客户端需要connect()连接服务器*@servaddr:是服务器的地址*/connect(sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr));write(sockfd, str, strlen(str));n = read(sockfd, buf, MAXLINE);printf("Response from server:\n");write(STDOUT_FILENO, buf, n);printf("\n");close(sockfd);return 0;}


原创粉丝点击