定义函数 int sendmsg(int s,const strcut msghdr *msg,unsigned int flags);
函数说明 sendmsg()用来将数据由指定的socket传给对方主机。参数s为已建立好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg 指向欲连线的数据结构内容,参数flags一般默认为0,详细描述请参考send()。 结构msghdr定义如下 struct msghdr { void *msg_name; /*Address to send to /receive from . */ socklen_t msg_namelen; /* Length of addres data */ strcut iovec * msg_iov; /* Vector of data to send/receive into */ size_t msg_iovlen; /* Number of elements in the vector */ void * msg_control; /* Ancillary dat */ size_t msg_controllen; /* Ancillary data buffer length */ int msg_flags; /* Flags on received message */ };
这个socket已经通过connect与服务器或客户端建立了连接...
----------------
这些方法可能客户端,也可能是服务端,因为一旦和服务端连接,服务端会有一个和客户端对应用Socket与其通信。
...
SOCKET newSock=accept(sSock,NULL,NULL);
...
nResult= recv(newSock,buff,strlen(buff),0);//这错了没?用sSock?
...
nResult=send(newSock/*sock*/,report,strlen(report),0);这是服务端的几行
哪几个是阻塞的?哪几个非阻塞?
还是说阻塞与否属于设计、编码,而与函数本身无关?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")//DLL的头文件extern "C"
{
#define DLLEXPORT __declspec(dllexport)SOCKET cSock;
sockaddr_in inSockAddr;
UINT uPort;DLLEXPORT int ConnectToSev(char * ip,UINT port);
DLLEXPORT int SendToSev(char* buffer,int length);
DLLEXPORT int RecvFromSev(char* buffer);
DLLEXPORT int SendAndRecv(char& buffer);
DLLEXPORT void CloseConnection(void);
}//DLL的源文件
DLLEXPORT int ConnectToSev(char * ip,UINT port)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested=MAKEWORD(2,0);
err=WSAStartup(wVersionRequested, &wsaData);
if(err!=0)
{
return FALSE;
} if(cSock!=NULL)
{
closesocket(cSock);
cSock=NULL;
}
cSock=socket(AF_INET,SOCK_STREAM,0); inSockAddr.sin_family=AF_INET;
inSockAddr.sin_addr.S_un.S_addr=inet_addr(ip);
inSockAddr.sin_port=ntohs(port); int ret=0;
int error=0;
ret=connect(cSock,(LPSOCKADDR)&inSockAddr,sizeof(inSockAddr)); if(ret==SOCKET_ERROR)
{
if(GetLastError()!=WSAEWOULDBLOCK)
printf("Is the Server opened?what about the Port?\n");
return FALSE;
}
printf("ConnectToSev() OK!\n");
return TRUE;
}DLLEXPORT int SendToSev(char* buffer,int length)
{
int ret=send(cSock,buffer,length,0);
if(ret==SOCKET_ERROR)
{
printf("SendToSev() error!\n");
return FALSE;
}
return TRUE;
}DLLEXPORT int RecvFromSev(char* str)
{
int ret=recv(cSock,str,strlen(str),MSG_DONTROUTE);
if(ret==SOCKET_ERROR)
{
printf("RecvFromSev() error!\n");
return FALSE;
}
return TRUE;
}DLLEXPORT int SendAndRecv(char& str)
{
if(send(cSock,&str,sizeof(str),0)==SOCKET_ERROR)
printf("SendAndRecv() error!");
recv(cSock,&str,1024,MSG_DONTROUTE);
return TRUE;
}DLLEXPORT void CloseConnection(void)
{
WSACleanup();
closesocket(cSock);
}//客户端
typedef int(*LPCTOSEV)(char *,UINT);
typedef int(*LPSTOSEV)(char *,int);
typedef int(*LPRCVSEV)(char *);
typedef void(*LPCLSCNT)(void);
LPCTOSEV pCToS;
LPSTOSEV pSToS;
LPRCVSEV pRFS;
//LPRS pSAndR;
LPCLSCNT pCC;
HINSTANCE hInst; char * IP={"127.0.0.1"};
UINT Port=4000; hInst=::LoadLibrary("TCPDLL.dll");
if(hInst==NULL)
printf("LoadLibrary fail!\n");
//return -1;
pCToS=(LPCTOSEV)GetProcAddress(hInst,"ConnectToSev");
pSToS=(LPSTOSEV)GetProcAddress(hInst,"SendToSev");
pRFS=(LPRCVSEV)GetProcAddress(hInst,"RecvFromSev");
//pSAndR=(LPRS)GetProcAddress(hInst,"SendAndRecv");
pCC=(LPCLSCNT)GetProcAddress(hInst,"CloseConnection"); //scanf("%s",IP);
//scanf("%d",&Port); int ret=0;
ret=pCToS(IP,Port);
if(ret==NULL)
{
printf("pCToS() error!\n");
return FALSE;
} char ch;
ch=getc(stdin);
for(;ch!='#';)
{
char str[]="Just a Try!\n";
ret=pSToS(str,strlen(str));
if(ret==NULL)
printf("pSToS() error!\n"); char * pStr="\0";
//char pStr[1024];
ret=pRFS(pStr);
if(ret==NULL)
{
printf("pRFS() error!\n");
//return FALSE;
}
printf("Server:%s\n",pStr);
ch=getc(stdin);
} pCC(); ::FreeLibrary(hInst);
return 0;//服务器端
WORD wVersion=MAKEWORD(2,0);
WSADATA wsData;
int err=WSAStartup(wVersion,&wsData);
if(err!=0)
printf("WSAStartup() error!\n"); SOCKET sock=socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
if(sock==INVALID_SOCKET)
printf("server socket() error!\n"); sockaddr_in addr;
addr.sin_family=AF_INET;
//addr.sin_addr.s_addr= htonl(INADDR_ANY);
addr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
addr.sin_port= htons(PORT); int nResult=bind(sock,(sockaddr*)&addr,sizeof(sockaddr));
if(nResult==SOCKET_ERROR)
printf("server bind() error!\n");table:
char ch;
printf("Input # to quit!\n");
scanf("%c",&ch);
if(ch=='#')
exit (0);
nResult=listen(sock,5);
if(nResult==SOCKET_ERROR)
{
printf("server listen() error!\n");
return FALSE;
} printf("Please try: telnet localhost 4000\n"); SOCKET newSock=accept(sock,NULL,NULL);
if(newSock==INVALID_SOCKET)
{
printf("server accept() error!\n");
goto table;
} char buff[1024];
//char * buff=NULL;
nResult= recv(newSock,buff,strlen(buff),0);
if(nResult==SOCKET_ERROR)
printf("server recv() error!\n");
buff[nResult]=NULL;
printf("Client:%s\n",buff); char report[]="You have alread connected!\n";
nResult=send(newSock/*sock*/,report,strlen(report),0);
if(nResult==SOCKET_ERROR)
printf("server send() error!\n"); printf("Success!\n"); goto table;有时间的帮忙看看
recv(经socket接收数据)
相关函数 recvfrom,recvmsg,send,sendto,socket
表头文件 #include
#include
定义函数 int recv(int s,void *buf,int len,unsigned int flags);
函数说明 recv()用来接收远端主机经指定的socket传来的数据,并把数据存到由参数buf 指向的内存空间,参数len为可接收数据的最大长度。
参数 flags一般设0。其他数值定义如下:
MSG_OOB 接收以out-of-band 送出的数据。
MSG_PEEK 返回来的数据并不会在系统内删除,如果再调用recv()会返回相同的数据内容。
MSG_WAITALL强迫接收到len大小的数据后才能返回,除非有错误或信号产生。
MSG_NOSIGNAL此操作不愿被SIGPIPE信号中断返回值成功则返回接收到的字符数,失败返回-1,错误原因存于errno中。
错误代码 EBADF 参数s非合法的socket处理代码
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断
EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断
ENOBUFS 系统的缓冲内存不足。
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。
范例 参考listen()。
recvfrom(经socket接收数据)
相关函数 recv,recvmsg,send,sendto,socket
表头文件 #include
#include
定义函数 int recvfrom(int s,void *buf,int len,unsigned int flags ,struct sockaddr *from ,int *fromlen);
函数说明 recv()用来接收远程主机经指定的socket 传来的数据,并把数据存到由参数buf 指向的内存空间,参数len 为可接收数据的最大长度。参数flags 一般设0,其他数值定义请参考recv()。参数from用来指定欲传送的网络地址,结构sockaddr 请参考bind()。参数fromlen为sockaddr的结构长度。
返回值 成功则返回接收到的字符数,失败则返回-1,错误原因存于errno中。
错误代码 EBADF 参数s非合法的socket处理代码
EFAULT 参数中有一指针指向无法存取的内存空间。
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此动作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。
send(经socket传送数据)
相关函数 sendto,sendmsg,recv,recvfrom,socket
表头文件 #include
#include
定义函数 int send(int s,const void * msg,int len,unsigned int falgs);
函数说明 send()用来将数据由指定的socket 传给对方主机。参数s为已建立好连接的socket。参数msg指向欲连线的数据内容,参数len则为数据长度。参数flags一般设0,其他数值定义如下
MSG_OOB 传送的数据以out-of-band 送出。
MSG_DONTROUTE 取消路由表查询
MSG_DONTWAIT 设置为不可阻断运作
MSG_NOSIGNAL 此动作不愿被SIGPIPE 信号中断。
返回值 成功则返回实际传送出去的字符数,失败返回-1。错误原因存于errno
错误代码 EBADF 参数s 非合法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此操作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。
范例 参考connect()
sendmsg(经socket传送数据)
相关函数 send,sendto,recv,recvfrom,recvmsg,socket
表头文件 #include
#include
定义函数 int sendmsg(int s,const strcut msghdr *msg,unsigned int flags);
函数说明 sendmsg()用来将数据由指定的socket传给对方主机。参数s为已建立好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg 指向欲连线的数据结构内容,参数flags一般默认为0,详细描述请参考send()。
结构msghdr定义如下
struct msghdr
{
void *msg_name; /*Address to send to /receive from . */
socklen_t msg_namelen; /* Length of addres data */
strcut iovec * msg_iov; /* Vector of data to send/receive into */
size_t msg_iovlen; /* Number of elements in the vector */
void * msg_control; /* Ancillary dat */
size_t msg_controllen; /* Ancillary data buffer length */
int msg_flags; /* Flags on received message */
};
返回值 成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno
错误代码 EBADF 参数s 非合法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间
ENOTSOCK 参数s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此操作会令进程阻断,但参数s的socket为不可阻断。
ENOBUFS 系统的缓冲内存不足
ENOMEM 核心内存不足
EINVAL 传给系统调用的参数不正确。
范例 参考sendto()。
sendto(经socket传送数据)
相关函数 send , sendmsg,recv , recvfrom , socket
表头文件 #include < sys/types.h >
#include < sys/socket.h >
定义函数 int sendto ( int s , const void * msg, int len, unsigned int flags, const
struct sockaddr * to , int tolen ) ;
函数说明 sendto() 用来将数据由指定的socket传给对方主机。参数s为已建好连线的socket,如果利用UDP协议则不需经过连线操作。参数msg指向欲连线的数据内容,参数flags 一般设0,详细描述请参考send()。参数to用来指定欲传送的网络地址,结构sockaddr请参考bind()。参数tolen为sockaddr的结果长度。
返回值 成功则返回实际传送出去的字符数,失败返回-1,错误原因存于errno 中。
错误代码 EBADF 参数s非法的socket处理代码。
EFAULT 参数中有一指针指向无法存取的内存空间。
WNOTSOCK canshu s为一文件描述词,非socket。
EINTR 被信号所中断。
EAGAIN 此动作会令进程阻断,但参数s的soket为补课阻断的。
ENOBUFS 系统的缓冲内存不足。
EINVAL 传给系统调用的参数不正确。
sendto, recvfrom 是UDP
服务器一个:SOCKET sSock
服务器调用accept()返回一个newSock这几个socket都用在哪里?
客户端调用connnect(),send(),recv()--调用自己的socket还是服务器的?
服务器调用accept(),send(),recv()--调用自己的socket还是客户端的?