/* * File: 1-3.c * Author: jinyong * * Linux sokcet * socket是网络编程的一种接口,它是一种特殊的I/O,用socket函数建立一个socket连接, * 此函数返回一个整型的描述符,随后进行数据传输。 * 通常,sokcet分为三种类型:流式sokcet、数据报socket和原始socket * * socket套接口的数据结构:sockadd、sockaddr_in * struct sockadd{ * unsigned short sa_family;//代表TCP/IP地址簇 * char sa_data[14];//IP地址和端口号 * } * * struct sockaddr_in{ * short int sin_family;//地址簇 * unsigned short int sin_port;//端口号 * struct in_addr sin_addr;//IP地址 * unsigned char sin_zero[8];//填充0以保持与struct sockaddr同样大小 * } * * 基于TCP网络编程常用函数及功能 * bind 将socket与本机上的一个端口绑定,随后就可以在该端口监听服务请求 * connect 面向连接的客户程序使用connect函数来配置socket,并与远端服务器建立一个TCP连接 * listen 使socket处于被动的监听状态,并为该socket建立一个输入数据队列,将到达的服务请求 * 保存在队列中,直到程序处理他们 * accept 让服务器接收客户的连接请求 * close 停止在该socket上的任何操作 * send 数据发送函数 * recv 数据接收函数 * * server端 * * Created on 2011年2月24日, 下午7:57 */ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/wait.h> #include <arpa/inet.h> #include <unistd.h> #define SERVERPORT 3333//服务器监听端口号 #define BACKLOG 10//最大同时连接数 /* * */ int main() { int sockfd, client_fd; //sockfd:监听socket,client_fd:数据传输socket struct sockaddr_in my_addr;//本地地址信息 struct sockaddr_in remote_addr;//客户地址信息 int sin_size; sockfd = socket(AF_INET, SOCK_STREAM, 0); /** * socket的建立 * int socket(int domain, int type, int protocal); * AF_INET:ipv4协议 * AF_INET6:ipv6协议 * domain: AF_LOCAL:Unix域协议 * AF_ROUTE:路由套接字 * AF_KEY:密匙套接字 * * type SOCK_STREAM:字节数据流套接字 * SOCK_DGRAM:数据报套接字 * SOCK_RAW:原始套接字 * * protocal 设为0,表示自动选择s * * 若成功则返回socket描述符,失败返回-1 */ my_addr.sin_family = AF_INET; my_addr.sin_port = htons(SERVERPORT);//htons把16位值从主机字节序转换成网络字节序 my_addr.sin_addr.s_addr = INADDR_ANY; bzero(&(my_addr.sin_zero), 8); //保持与struct sockaddr同样大小 bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)); /** * 将sokect与本机上的一个端口绑定,随后就可以在该端口监听服务请求 * int bind(int sockfd, struct sockaddr *myaddr, int addrlen); * sockfd:调用socket返回的socket描述符 * my_addr:指向包含有本机IP地址及端口号等信息的sockaddr类型的指针 * addrlen:结构提长度sizeof(struct sockaddr) * 成功返回0,失败返回-1 */ listen(sockfd, BACKLOG); /** * 使socket处于被动的监听模式,并为该socket建立一个输入数据队列, * 将到达的服务请求保存在此队列中,直到程序处理他们 * int listen(int sockfd, int backlog); * backlog:最大主机连接数 * 若成功返回0,失败返回-1 * */ while(1) { sin_size = sizeof(struct sockaddr_in); client_fd = accept(sockfd, (struct sockaddr*)&remote_addr, &sin_size); /** * 让服务器接收客户的连接请求 * int accept(int sockfd, void *addr, int *addrlen); * addr:主机端的信息 * addrlen:struct sockaddr_in数据结构的长度 * */ sleep(5); printf("收到一个来自:%s/n", inet_ntoa(remote_addr.sin_addr)); if(!fork()){//创建子进程 send(client_fd, "连接上了/n", 26,0); /** * 数据发送 * int send(int sockfd, const void *msg, int flags); * sockfd是用来传输数据的socket描述符。 * msg:指向要发送数据的指针 * len:以字节为单位的数据长度 * flags:一般情况设置为0 * * send函数返回实际发送出的字节数,失败返回-1 */ }else{ close(client_fd); } } return (EXIT_SUCCESS); }