Linux socket 基础函数及使用范例
来源:互联网 发布:大数据 云计算 关系 编辑:程序博客网 时间:2024/05/17 09:36
以c语言开发的socket通信
1 成功时返回一个整型的Socket描述符,失败时返回-1
2 domain:套接字中使用的协议族信息(protocol family)
常用的两个:PF_INET :IPv4互联网协议族
PF_INET6:IPv6互联网协议族
3 type:套接字类型(数据传输方式)
具有代表性的两个:
SOCK_STREAM:面相连接的套接字,流式,面向连接的比特流,顺序、可靠、双向,用于TCP通信
SOCK_DGRAM :面向消息的套接字,数据报式,无连接的,定长、不可靠、常用语于UDP通信
4 protocol:最终决定采用的协议。一般情况下为0;除非同一个协议族中存在多个传输方式相同的协议时,需要具体指定
1 将套接字与指定端口相连,成功返回0,失败返回-1
2 sockfd:前面调用socket()函数返回的文件描述符
3 struct sockaddr *myaddr:指向sockaddr结构体的指针(该结构体中保存有端口和IP地址信息)
4 socklen_t addrlen:指定了以addr所指向的地址结构体的字节长度
1 监听连接请求,成功返回0,失败返回-1
2 sockfd 处于监听状态,并且最多允许有backlog个客户端处于连接待状态
1 服务器调用accept()接受连接,如果没有客户端的连接请求就阻塞等待直到有客户端连接上
2 成功则返回一个新的套接字用于连接,与客户端进行点对点的通信
3 sockfd:用于监听的文件描述符,即第一次socket()函数产生的
4 sockaddr *myaddr:传出参数,存有连接好的客户端的IP地址和端口信息,设为NULL表示不关心
5 sockaddr *addrlen:传入传出参数,传入的是调用者提供的缓冲区myaddr的长度以避免缓冲区溢出问题。传出的是客户端
地址结构体的实际长度(有可能没有占满调用者提供的缓冲区)如果给cliaddr参数传NULL表示不关心客户端的地址
其次,客户端:
1 连接服务器,成功返回0,失败返回-1
2 struct sockaddr *serv_addr:服务器的IP地址和端口信息
对于Linux而言,socket是文件的一种,因此读写文件同样适用于socket
写文件:
1 成功返回写入的字节数,失败返回-1
2 int fd:文件描述符
3 const void *buf:保存写入数据的缓冲区
4 size_t nbytes:要传输数据的字节数
读文件:
2 int fd:文件描述符
3 const void *buf:保存接收数据的缓冲区
4 size_t nbytes:要接受数据的最大字节数
收发数据函数:
1 SOCKET s:接受套接字
2 const char FAR *buf:发送数据缓冲区
3 int len:实际发送的长度(字节数)
4 int flags:该参数一般置0;
其他参数:
MSG_DONTROUTE:绕过路由表查找
MSG_DONTWAIT:此操作非阻塞
MSG_OOB:发送带外数据
5 成功则返回实际发送字节数,失败则返回SOCKET_ERROR
1 SOCKET s:接受套接字
2 char FAR * char:接受缓冲区
3 int len:接受缓冲区长度
4 int flags:该参数一般置0;
其他参数:
MSG_DONTWAIT:此操作非阻塞
MSG_OOB:接受带外数据
MSG_PEEK:窥看外来信息
MSG_WAITALL:等待所有数据
5 成功则返回实际发送字节数,失败则返回SOCKET_ERROR
1 该函数比send()多了两个参数:
2 const struct sockaddr *to:指向目的机的IP地址和端口信息
3 int tolen:struct sockaddr 的大小
1 int sockfd:接受套接字
2 void *buf:接受缓冲区
3 int len:接受缓冲区长度
4 unsigned int flags:同recv()
5 struct sockaddr *from:信息来源机的地址信息
6 int *fromlen:struct sockaddr的大小
使用范例:
htons htonl ntohl ntohs
字符串转32位大端序整型值
in_addr_t inet_addr(const char * string);
首先Linux环境下的服务器端:
#include<sys/socket.h>int socket(int domain,int type,int protocol);说明:
1 成功时返回一个整型的Socket描述符,失败时返回-1
2 domain:套接字中使用的协议族信息(protocol family)
常用的两个:PF_INET :IPv4互联网协议族
PF_INET6:IPv6互联网协议族
3 type:套接字类型(数据传输方式)
具有代表性的两个:
SOCK_STREAM:面相连接的套接字,流式,面向连接的比特流,顺序、可靠、双向,用于TCP通信
SOCK_DGRAM :面向消息的套接字,数据报式,无连接的,定长、不可靠、常用语于UDP通信
4 protocol:最终决定采用的协议。一般情况下为0;除非同一个协议族中存在多个传输方式相同的协议时,需要具体指定
例子:
1 IPv4协议族中面向连接的套接字(TCP套接字)
int tcp_socket = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);2 IPv4协议族中面向消息的套接字(UDP套接字)
int udp_socket = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP);
int bind(int sockfd,struct sockaddr *myaddr,socklen_t addrlen);说明:
1 将套接字与指定端口相连,成功返回0,失败返回-1
2 sockfd:前面调用socket()函数返回的文件描述符
3 struct sockaddr *myaddr:指向sockaddr结构体的指针(该结构体中保存有端口和IP地址信息)
4 socklen_t addrlen:指定了以addr所指向的地址结构体的字节长度
int listen(int sockfd,int backlog);说明:
1 监听连接请求,成功返回0,失败返回-1
2 sockfd 处于监听状态,并且最多允许有backlog个客户端处于连接待状态
int accept(int sockfd,struct sockaddr *myaddr,socklen_t *addrlen)说明:
1 服务器调用accept()接受连接,如果没有客户端的连接请求就阻塞等待直到有客户端连接上
2 成功则返回一个新的套接字用于连接,与客户端进行点对点的通信
3 sockfd:用于监听的文件描述符,即第一次socket()函数产生的
4 sockaddr *myaddr:传出参数,存有连接好的客户端的IP地址和端口信息,设为NULL表示不关心
5 sockaddr *addrlen:传入传出参数,传入的是调用者提供的缓冲区myaddr的长度以避免缓冲区溢出问题。传出的是客户端
地址结构体的实际长度(有可能没有占满调用者提供的缓冲区)如果给cliaddr参数传NULL表示不关心客户端的地址
int close(int filedes);说明:关闭套接字
其次,客户端:
int socket(int domain,int type,int protocol);同上:
int connect(int sockfd,struct sockaddr *serv_addr,socklen_t addrlen);说明:
1 连接服务器,成功返回0,失败返回-1
2 struct sockaddr *serv_addr:服务器的IP地址和端口信息
int close(int filedes);
对于Linux而言,socket是文件的一种,因此读写文件同样适用于socket
写文件:
#include<unistd.h>//typedef unsigned int size_t//typedef signe4 int ssize_t ssize_t write(int fd,const void *buf,size_t nbytes);
1 成功返回写入的字节数,失败返回-1
2 int fd:文件描述符
3 const void *buf:保存写入数据的缓冲区
4 size_t nbytes:要传输数据的字节数
读文件:
ssize_t read(int fd,void *buf,size_t nbytes);1 成功返回接受的字节数(但遇到文件结尾则返回0),失败则返回-1
2 int fd:文件描述符
3 const void *buf:保存接收数据的缓冲区
4 size_t nbytes:要接受数据的最大字节数
收发数据函数:
TCP:
int send(SOCKET s,const char FAR *buf,int len,int flags);说明:
1 SOCKET s:接受套接字
2 const char FAR *buf:发送数据缓冲区
3 int len:实际发送的长度(字节数)
4 int flags:该参数一般置0;
其他参数:
MSG_DONTROUTE:绕过路由表查找
MSG_DONTWAIT:此操作非阻塞
MSG_OOB:发送带外数据
5 成功则返回实际发送字节数,失败则返回SOCKET_ERROR
int recv(SOCKET s,char FAR *char,int len,int flags);说明:
1 SOCKET s:接受套接字
2 char FAR * char:接受缓冲区
3 int len:接受缓冲区长度
4 int flags:该参数一般置0;
其他参数:
MSG_DONTWAIT:此操作非阻塞
MSG_OOB:接受带外数据
MSG_PEEK:窥看外来信息
MSG_WAITALL:等待所有数据
5 成功则返回实际发送字节数,失败则返回SOCKET_ERROR
UDP:int sendto(int sockfd,const void *msg,int len unsigned int flags,const struct sockaddr *to,int tolen);说明:
1 该函数比send()多了两个参数:
2 const struct sockaddr *to:指向目的机的IP地址和端口信息
3 int tolen:struct sockaddr 的大小
int recvfrom(int sockfd,void *buf,int len,unsigned int flags,struct sockaddr *from,int *fromlen);说明:
1 int sockfd:接受套接字
2 void *buf:接受缓冲区
3 int len:接受缓冲区长度
4 unsigned int flags:同recv()
5 struct sockaddr *from:信息来源机的地址信息
6 int *fromlen:struct sockaddr的大小
使用范例:
//Server#include<stdio.h>#include<stdlib.h>#incldue<string.h>#incldue<unistd>#incldue<arpa/inet.h>#incldue<sys/socket.h>void error_handing(char *message);int main(int argc,char *argv[]){int serv_sock;int clnt_sock;struct sockaddr_in serv_addr;struct sockaddr_in clnt_addr;socklen_t clnt_addr_size;char message[] = "Hello World!";if(argc != 2)//提示输入端口{printf("Usage :%s <port>\n",argv[0]);exit(1);}serv_sock = socket(PF_INET,SOCK_STREAM,0);if(serv_sock == -1)error_handing("socket() error!\n");memset(serv_addr,0,sizeof(serv_addr)); //void *memset(void *s,int c,size_t n)//将已开辟内存空间 s 的首 n 个字节的值设为值 cserv_addr.family = AF_INET;serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);serv_addr.sin_port = htons(atoi(argv[1]));if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1)error_handing("bind() error");if(listen(serv_sock,5) == -1)error_handing("listen() error");clnt_addr_size = sizeof(clnt_addr);clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_addr,&clnt_addr_size);if(clnt_sock == -1)error_handing("accept() error");write(clnt_sock,message,sizeof(message));return 0;}void error_handing(char *message){fputs(message,stderr); //stderr为标准错误输出,在屏幕上输出由当前文件名和这条调用所在的行号组成的信息fputc('\n',stderr);exit(1);}
//Client#include<stdio.h>#include<stdlib.h>#incldue<string.h>#incldue<unistd>#incldue<arpa/inet.h>#incldue<sys/socket.h>void error_handing(char *message);int main(int argc,char* argv[]){int sock;struct sockaddr_in serv_addr;char message[30];int str_len;if(argc != 3){printf("Usage :%s <IP><Port>\n",argv[0]);exit(1);}sock = socket(PF_INET,SOCK_STREAM,0);if(sock == -1)error_handing("sock error!\n");memset(&serv_addr,0,sizeof(serv_addr));serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = inet_addr(argv[1]);serv_addr.sin_port = htons(atoi(argv[2]);if(connect(sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr)) == -1)error_handing("connect() error!\n");str_len = read(sock,message,sizeof(message)-1);if(str_len == -1)error_handing("read error!\n");printf("Message from server: %s \n",message);close(sock);return 0;}void error_handing(char *message){fputs(message,stderr);fputc('\n',stderr);exit(1);}
注:
struct sockaddr_in //该结构体针对Ipv4{sa_family_t sin_family;uint16_tsin_port;struct in_addr sin_addr;char sin_zero[8];}struct in_addr{In_addr_ts_addr;}struct sockaddr //此结构不止针对Ipv4{sa_family_tsin_family;charsa_data[14];}网络字节序,即大端序,网络传输统一用大端序
htons htonl ntohl ntohs
字符串转32位大端序整型值
in_addr_t inet_addr(const char * string);
在转换的同时自动加入sin_addr结构体中char* addr = "127.232.124.79"struct sockaddr_in addr_inetinet_aton(addr,&addr_inet.sin_addr)
//WSAStringToAddress、WSAAddressToString用于windows中IP地址与字符串的转换#include "stdafx.h"#include<stdio.h>#include<stdlib.h>#include<WinSock2.h>int _tmain(int argc, _TCHAR* argv[]){char *strAddr = "196.168.1.154:8000";char strAddrBuff[50];SOCKADDR_IN servAddr;int size;WSADATA wsaData;WSAStartup(MAKEWORD(2, 2), &wsaData);size = sizeof(servAddr);WSAStringToAddress(strAddr, AF_INET, NULL, (SOCKADDR*)&servAddr, &size);size = sizeof(strAddrBuff);WSAAddressToString((SOCKADDR*)&servAddr, sizeof(servAddr), NULL, strAddrBuff,(DWORD*)&size);printf("Second conv result:%s \n", strAddrBuff);WSACleanup();system("pause");return 0;}//accept()在客户端connect()之前为阻塞状态。
0 0
- Linux socket 基础函数及使用范例
- windows sockets TCP基础函数及范例
- Socket编程基础范例
- erlang函数说明及使用范例
- Linux socket之一:基础函数
- Linux socket之一:基础函数
- socket套接字使用范例
- android socket的使用范例
- 【Linux Socket 编程入门】04 - socket编程最常使用的函数及数据结构
- CString 常使用的成员函数及范例
- linux定时器使用范例
- 递归函数及Java范例
- Linux socket 地址及常用函数
- Linux socket默认值及setsockopt函数用法
- spark sql基础使用范例
- Linux网络编程:socket文件传输范例
- Linux网络编程:socket文件传输范例
- QStyle的使用及范例
- [C#]骑士飞行棋
- POJ - 1797----Heavy Transportation(Dijkstra)
- Scala学习笔记 --- 理解术语面向对象编程和函数式编程
- 【nginx,apache】thinkphp ,laravel,yii2开发运行环境搭建
- java 中的集合(特别重要)
- Linux socket 基础函数及使用范例
- Java Web 常用工具类(持续更新)
- 在线 Python运行工具
- 浅析I/O模型及其设计模式
- task_struct 结构描述
- Java初学之命令行参数
- Poj 2195 Going Home(费用流)
- go各种初步技能
- 剑指offer 二叉树中和为某一值的路径