linux socket

2/10/2017来源:ASP.NET技巧人气:1074

int socket(int domain,int type,int PRotocl); domain:协议族选项,AF_INET(ipv4),AF_INET6(ipv6) type:SOCK_STREAM(字节流)、SOCK_DGRAM(数据报流) protocl:通常为0; int bind(socket s,(sockaddr*)&sever,socklen_t len); s:套接字 sever:绑定的地址 len:字节长度 int listen(socket s,int backlog); backlog:等待连接队列中的最大数目,SOMAXCONN:128 int connect(socket s,(sockaddr*)sever,socket_t len); socket accept(socket s,(sockaddr*)client,socklen_t clientlen); 返回一个新的socket描述符 fcntl将socket设置成阻塞模式和非阻塞模式 int fcntl(int fd,int cmd,...) cmd:GETFL(获取文件描述符)、SETFL(设置文件描述符) 设置成非阻塞 int flag=fcntl(sock,GETFL,0); flag|=O_NONBLOCK; fcntl(sock,SETFL,flag); 变成阻塞 int flag=fcntl(sock,GETFL,0); flag&=~O_NONBLOCK; fcntl(sock,SETFL,flag); ioctlsocket(s,long cmd,u_long* argp); cmd:输入输出控制命令,FIONBIO,FIONREAD,SIOCATMARK; argp:指向cmd指针; FIONBIO:默认从阻塞模式转非阻塞,或者相反转变,*argp=TRUE(非0),socket变非阻塞,*argp=FALSE(0),socket阻塞; unsigned long ul=1; ioctlsocket(s,FIONBIO,(unsigned long*)&ul); int getsockopt(socket s,int level,int optname,void* optval,socket_t *len); int setsockopt(socket s,int level,int optname,void* optval,socket_t *len); levle:选项协议层,SOL_SOCKET(普通套接字),IPPROTO_IP(IP),IPPROTO_TCP(TCP) optname:不同选项层对应不同的取值范围,SO_RCVBUF optval:指向返回项的缓冲 optlen:选项长度 设置接收缓冲区例子 int rcvbuf=1024*10;

setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&rcvbuf,sizeof(int));

示例:

#ifndef _MY_SOCKET_
#define _MY_SOCKET_

#ifdef WIN32
#include <Windows.h>
#include <WinSock.h>
#else
#include <sys/socket.h>
#include <sys/types.h>
#endif
class Socket
{
public:
	enum EMode{BLOCKING,NOBLOCKING};

public:
	Socket();
	~Socket();
	int Connect(char *destaddr,unsigned short port);
	int Bind(char *paddr,int port);
	int Listen();
	int Accept();
	void Ioctlsocket(EMode mode);
	void SetBufferSize();
	int RecvData(char *recvbuf,int len);
	int SendData(char *sendbuf,int len);

private:
	int s;//监听socket
	int socks;//建联socket
};

#endif
#include "Socket.h"

Socket::Socket()
{
#ifdef WIN32
	/* 加载socket dll 库,第一个调用的函数
	WSAStartup(Word wVersionRequired,LPWSADATA lpWSAData);
	wVersionRequired:动态库版本,MAKEWORD(X,Y)指定参数;
	lpWSAData:动态库相关信息*/

	LPWSADATA lpWSAData={0};
	int iRet=WSAStartup(MAKEWORD(2,2),&lpWSAData);
	if(iRet!=0){
		WSACleanup();
	}
	
#else 
	
#endif
	s=socket(AF_INET,NULL,SOCK_STREAM);			  
}

Socket::~Socket()
{
	closesocket(s);
}

int Socket::Bind(char* paddr,int port)
{
	sockaddr_in severaddr;
	severaddr.sin_addr.s_addr=inet_addr(paddr);
	severaddr.sin_family=AF_INET;
	severaddr.sin_port=htons(port);
	return bind(s,(sockaddr*)&severaddr,sizeof(severaddr));
}

int Socket::Connect(char *destaddr,unsigned short port){
	sockaddr_in server;
	server.sin_addr.s_addr=inet_addr(destaddr);
	server.sin_family=AF_INET;
	server.sin_port=htons(port);
	return connect(s,(sockaddr*)&server,sizeof(server));

}

int Socket::Listen(){
	listen(s,4);
}

int Socket::Accept()
{
	sockaddr_in client;
	int client_len=sizeof(client);
	/*client 内容接受后客户填充*/
	int socks=accept(s,(sockaddr*)&client,&client_len);
	if(socks==-1){
		return false;
	}
	return true;
}

void Socket::Ioctlsocket(EMode mode){
	/*ioctlsocket(s,long cmd,u_long* argp);
	cmd:输入输出控制命令,FIONBIO,FIONREAD,SIOCATMARK;
	argp:指向cmd指针;
	FIONBIO:默认从阻塞模式转非阻塞,或者相反转变,*argp=TRUE(非0),socket变非阻塞,*argp=FALSE(0),socket阻塞;
	*/
	if(mode==EMode::NOBLOCKING)
	{
		unsigned long ul=1;
		ioctlsocket(s,FIONBIO,(unsigned long*)&ul);
	}
	else{
		unsigned long ul=0;
		ioctlsocket(s,FIONBIO,(unsigned long*)&ul);
	}
	

}
void Socket::SetBufferSize()
{
	long rcvbuf=1024*10;
	setsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&rcvbuf,sizeof(long));

}
int Socket::RecvData(char *recvbuf,int len){
	return recv(s,recvbuf,len,0);
}
int Socket::SendData(char *sendbuf,int len){
	return send(s,sendbuf,len,0);
}