#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 SERVPORT 3333
#define MAXDATASIZE 100 /*每次最大数据传输量 */
main(int argc, char *argv[]){
int sockfd, recvbytes;
char buf[MAXDATASIZE];
struct hostent *host;
struct sockaddr_in serv_addr;
if (argc < 2) {
fprintf(stderr,"Please enter the server's hostname!\n");
exit(1);
}
if((host=gethostbyname(argv[1]))==NULL) {
herror("gethostbyname出错!");
exit(1);
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
perror("socket创建出错!");
exit(1);
}
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERVPORT);
serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(serv_addr.sin_zero),8);
if (connect(sockfd, (struct sockaddr *)&serv_addr, \
sizeof(struct sockaddr)) == -1) {
perror("connect出错!");
exit(1);
}
if ((recvbytes=recv(sockfd, buf, MAXDATASIZE, 0)) ==-1) {
perror("recv出错!");
exit(1);
}
buf[recvbytes] = '\0';
printf("Received: %s",buf);
close(sockfd);
}
今天了解了一下socket编程。按照网上的例子写了个Client/Server的简单例子!
在写代码过程中,有几个问题很让我费解!
如上代码,是一个客户段程序,其中通过方法gethostbyname进行域名于IP的转换。返回一个hostend的结构体。如下:
struct hostent {
char *h_name; /* 主机的官方域名 */
char **h_aliases; /* 一个以NULL结尾的主机别名数组 */
int h_addrtype; /* 返回的地址类型,在Internet环境下为AF-INET */
int h_length; /* 地址的字节长度 */
char **h_addr_list; /* 一个以0结尾的数组,包含该主机的所有地址*/
};
#define h_addr h_addr_list[0] /*在h-addr-list中的第一个地址*/
sockaddr_in结构体:
struct sockaddr_in {
short int sin_family; // Address family
unsigned short int sin_port; // Port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // Same size as struct sockaddr
};
sockaddr结构体:
struct sockaddr {
unsigned short sa_family; // address family, AF_xxx
char sa_data[14]; // 14 bytes of protocol address
};
in_addr结构体:
struct in_addr {
unsigned long s_addr; // that’s a 32-bit long, or 4 bytes
};
在填充sockaddr_in结构体时:serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
sockaddr_in与sockaddr都是16个字节,只是sockaddr的表现形式更形象,对象化而已。而in_addr结构体就是一个long型
可以猜测h_addr_list是一个4字节网络字节序的in_addr,只是使用char*来表示,h_addr与struct in_addr其实形式是一样的。然后将host->h_addr强转成struct in_addr格式的指针,最后取值。(哈哈,这个就是C比Java强悍的地方,指针可真是一把双面刃).
分享到:
相关推荐
在Linux Socket编程中,我们需要定义服务器和客户端的网络地址,这通常使用`struct sockaddr_in`结构体完成。包含IP地址和端口号。 ```c struct sockaddr_in server; server.sin_family = AF_INET; server.sin_addr...
- `addr`指向一个`sockaddr`结构体,通常使用`sockaddr_in`结构体来指定IPv4地址和端口。 - `addrlen`是`addr`结构体的大小。 `sockaddr_in`结构体如下: ```c struct sockaddr_in { sa_family_t sin_family;...
在这个详解中,我们将深入理解socket编程的基础知识,包括sockaddr_in结构体及其在创建套接字时的作用。 首先,`sockaddr`是一个通用的地址结构,用于存储不同地址家族的地址信息。它包含一个`sa_family`字段,用来...
struct sockaddr_in serv_addr; sockfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");...
struct sockaddr_in 结构体由四个成员组成:sin_family、sin_port、sin_addr 和 sin_zero。sin_family 是 short int 类型,用于指定地址族,如 AF_INET;sin_port 是 unsigned short int 类型,用于指定端口号;sin_...
struct sockaddr_in server_addr, client_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(12345); // 设置监听端口 inet_pton(AF_INET...
struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(8888); server_addr.sin_addr.s_addr = INADDR_ANY; bind(server_fd, (struct sockaddr*)&server_addr, ...
在套接字编程中,还有其他一些重要的结构体,例如sockaddr_in结构体、sockaddr_in6结构体等。 struct sockaddr_in { short int sin_family; /* Address family */ unsigned short int sin_port; /* Port number *...
IPv4的Socket地址结构是定长的,定义在`sockaddr_in`结构体中。 ```c struct in_addr { uint32_t s_addr; // 32位IP地址,网络字节序 }; struct sockaddr_in { uint8_t sin_len; sa_family_t sin_family; // ...
总的来说,socket函数是网络编程的核心,而`sockaddr`和`sockaddr_in`结构体则是实现网络连接的关键。掌握这些基础知识,无论是初学者还是经验丰富的开发者,都能更有效地构建高效可靠的网络应用程序。
struct sockaddr_in remote_addr; /* client address */ int sin_size; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } int opt = SO_REUSEADDR; setsockopt...
struct sockaddr_in my_addr; my_addr.sin_family = AF_INET; // 设置地址族 my_addr.sin_port = 0; // 自动分配端口号 // 其他初始化... ``` 通过以上内容,我们可以了解到Socket编程的基本原理及其在Linux环境中...
- 定义 `sockaddr_in` 类型的变量 `addr`,设置端口号为 3010 并使用 `INADDR_ANY` 表示可以绑定到本机的任意 IP 地址。 - 调用 `bind` 函数绑定套接字 `s` 到 `addr` 所代表的地址。 - 如果 `bind` 函数成功执行,...
struct sockaddr_in server_addr, client_addr; socklen_t len = sizeof(client_addr); // (1) 建立一个套接字描述符,定义网络类型,协议类型和具体的协议标志 server_socket = socket(AF_INET, SOCK_STREAM, ...