nsigned char sin_zero[8];
};
addrlen为sockaddr的长度。
3、connect函数
syntax:
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)。 int conn = connect(sock, (struct sockaddr *)&my_addr, sizeof(my_addr)) 。 int ret=connect(cfd,(struct sockaddr *)&sockaddr_out,sizeof(sockaddr_out))。
功能说明:
客户端发送服务请求。成功返回0,否则返回-1,并置errno。
参数说明:
sock_fd是socket函数返回的socket描述符;serv_addr是包含远端主机IP地址和端口号的指针;addrlen是结构sockaddr_in的长度。
4、listen函数
syntax:
int listen(int sock_fd, int backlog);
功能说明:
等待指定的端口的出现客户端连接。调用成功返回0,否则,返回-1,并置errno.
参数说明:
sock_fd 是socket()函数返回值;
backlog指定在请求队列中允许的最大请求数
5、accecpt函数
syntax:
int new_server_socket_fd = accept(server_socket_fd, (struct sockaddr*)&client_addr, &client_addr_length)。int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)。int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)。
功能说明:
用于接受客户端的服务请求,成功返回新的套接字描述符,失败返回-1,并置errno。
参数说明:
sock_fd是被的socket描述符,
addr通常是一个指向sockaddr_in变量的指针,
addrlen是结构sockaddr_in的长度。
6、write函数
syntax:
ssize_t write(int fd, const void *buf, size_t count)。ssize_t write (int fd, const void *buf, size_t count)。int write(int fd,void *buf,size_t nbytes)。
功能说明:
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1.并设置errno变量.
在网络程序中,当我们向套接字文件描述符写时有俩种可能:
1)write的返回值大于0,表示写了部分或者是全部的数据.
2)返回的值小于0,此时出现了错误.需要根据错误类型来处理.
如果错误为EINTR表示在写的时候出现了中断错误.
如果错误为EPIPE表示网络连接出现了问题.
7、read函数
syntax:
ssize_t read(int fd,void *buf,size_t nbyte)
函数说明:
函数返回一个非负值是表示成功地读取了多少字节。从一个文件流中读数据,读取count个元素,每个元素size字节.如果调用成功返回count.返回实际读取size*count字节.如不成功linux socket函数参数,返回实际读取的元素个数。调用该方法成功时返回同样为读取文件的实际字节数,错误则返回-1,错误代码存放入errno中可以查询帮助定位错误原因。
如果错误为EINTR说明读是由中断引起的,
如果错误是ECONNREST表示网络连接出了问题.
8、close函数
syntax:
int close(sock_fd);
说明:
当所有的数据操作结束以后,你可以调用close()函数来释放该socket,从而停止在该socket上的任何数据操作:
函数运行成功返回0,否则返回-1
二、socket编程的其他函数说明
1、 网络字节顺序及其转换函数
1) 网络字节顺序
每一台机器内部对变量的字节存储顺序不同,而网络传输的数据是一定要统一顺序的。所以对内部字节表示顺序与网络字节顺序不同的机器,
一定要对数据进行转换,从程序的可移植性要求来讲,就算本机的内部字节表示顺序与网络字节顺序相同也应该在传输数据以前先调用数据转换函数,
以便程序移植到其它机器上后能正确执行。真正转换还是不转换是由系统函数自己来决定的。
2) 有关的转换函数
unsigned short crc16_ibm(unsigned char *puchmsg, unsigned int usdatalen)。unsigned short crc16_xmodem(unsigned char *puchmsg, unsigned int usdatalen)。unsigned short crc16_modbus(unsigned char *puchmsg, unsigned int usdatalen)。
主机字节顺序转换成网络字节顺序,对无符号短型进行操作4bytes
表示对应一个long long int或unsigned long long int数据。: 看到了,decimal constant的优先级是int, long, long long, hexadecimal constant的优先级是int, unsigned int, long int , unsigned int。cwnd::onwndmsg(unsigned int message=514, unsigned int wparam=0, long lparam=2228296, long * presult=0x0024ed78) line 2548c++。
主机字节顺序转换成网络字节顺序,对无符号长型进行操作8bytes
unsigned short crc16_ibm(unsigned char *puchmsg, unsigned int usdatalen)。unsigned short crc16_xmodem(unsigned char *puchmsg, unsigned int usdatalen)。unsigned short crc16_modbus(unsigned char *puchmsg, unsigned int usdatalen)。
网络字节顺序转换成主机字节顺序,对无符号短型进行操作4bytes
* unsigned long int ntohl(unsigned long int netlong):
网络字节顺序转换成主机字节顺序,对无符号长型进行操作8bytes
注:以上函数原型定义在netinet/in.h里
2、IP地址转换
有三个函数将数字点形式表示的字符串IP地址与32位网络字节顺序的二进制形式的IP地址进行转换
(1) unsigned long int inet_addr(const char *cp):该函数把一个用数字和点表示的IP地址的字符串转换成一个无符号长整型,如:struct sockaddr_inina
ina.sin_addr.s_addr=inet_addr('202.206.17.101')
该函数成功时:返回转换结果;失败时返回常量INADDR_NONE,该常量=-1,二进制的无符号整数-1相当于255.255.255.255,这是一个广播地址,所以在程序中调用iner_addr()时,一定要人为地对调用失败进行处理。由于该函数不能处理广播地址,所以在程序中应该使用函数inet_aton()。
(2)int inet_aton(const char * cp,struct in_addr *inp):此函数将字符串形式的IP地址转换成二进制形式的IP地址;成功时返回1,否则返回0,转换后的IP地址存储在参数inp中。
(3) char * inet_ntoa(struct in-addrin):将32位二进制形式的IP地址转换为数字点形式的IP地址,结果在函数返回值中返回,返回的是一个指向字符串的指针。
3、字节处理函数
Socket地址是多字节数据,不是以空字符结尾的,这和C语言中的字符串是不同的。Linux提供了两组函数来处理多字节数据,一组以b(byte)开头,是和BSD系统兼容的函数,另一组以mem(内存)开头,是ANSIC提供的函数。
以b开头的函数有:
(1) void bzero(void * s,intn):将参数s指定的内存的前n个字节设置为0,通常它用来将套接字地址清0。
memmove(拷贝内存内容) 定义函数 void * memmove void *dest,const void *src,size_t n 。5) 将内存复制到所映射的物理文件上面 flushmapviewoffile函数可以将内存里面的内容dump到物理磁盘上面 flushviewoffile 把文件映射视图中的修改的内容或全部写回到磁盘文件中 bool flushviewoffile( lpcvoid lpbaseaddress, // 修改内容的起始地址 dword dwnumberofbytestoflush // 修改的字节数目 )。 其它内存块操作的函数 memccpy(拷贝内存内容) 定义函数 void * memccpy void *dest, const void * src, int c,size_t n 。
(3) int bcmp(const void * s1,const void * s2linux socket函数参数,intn):比较参数s1指定的内存区域和参数s2指定的内存区域的前n个字节内容,如果相同则返回0,否则返回非0。
注:以上函数的原型定义在strings.h中。
以mem开头的函数有:
(1) void * memset(void * s,int c,size_tn):将参数s指定的内存区域的前n个字节设置为参数c的内容。
(2) void * memcpy(void * dest,const void * src,size_tn):功能同bcopy(),区别:函数bcopy()能处理参数src和参数dest所指定的区域有重叠的情况,memcpy()则不能。
(4) int memcmp(const void * s1,const void * s2,size_tn):比较参数s1和参数s2指定区域的前n个字节内容,如果相同则返回0,否则返回非0。
注:以上函数的原型定义在string.h中。
二、程序说明
本使用tcp协议进行通信,服务端进行,在收到客户端的连接后,发送数据给客户端;客户端在接受到数据后打印出来,然后关闭。
1、client.c
#include
#include
#include
#include
#include
#include
int main()
{
int cfd;
int recbytes;
int sin_size;
char buffer[1024]={0};
struct sockaddr_in s_add,c_add;
unsigned short portnum=0x8888;
printf('Hello,welcome to client !\r');
cfd = socket(AF_INET, SOCK_STREAM, 0);