|
|
|
|
|
|
ヘッダー |
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h> |
#include <winsock2.h>
#pragma comment(lib, "WS2_32.LIB") |
#include <afxsock.h> |
import java.net.*; |
using System.Net.Sockets |
初期化 |
なし |
WORD ver=MAKEWORD(2,2);
WSADATA wsa;
if(WSAStartup(ver,&wsa) != 0) fprintf(stderr,"WSAStartup error\n"); |
AfxSocketInit(); |
なし |
|
終了 |
なし |
WSACleanup(); |
なし |
なし |
|
TCPサーバー |
int ssoc=socket(AF_INET,SOCK_STREAM,0);
if(ssoc<0) perror("socket error"); |
SOCKET ssoc=socket(AF_INET,SOCK_STREAM,0);
if(ssoc==INVALID_SOCKET) fprintf(stderr,"socket error:%d\n",WSAGetLastError()); |
CAsyncSocketを継承したクラス(例:CServerSocket)を作る。
CServerSocket ssoc;
ssoc.Create(ポート, SOCK_STREAM); |
ServerSocket ssoc = new
ServerSocket(ポート,バックログ数); |
Socket ssoc = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp); |
struct sockaddr_in addr={ AF_INET };
addr.sin_port = htons(ポート);
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(ssoc,(struct sockaddr*)addr,sizeof(addr))<0) perror("bind
error"); |
struct sockaddr_in addr={ AF_INET };
addr.sin_port = htons(ポート);
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(ssoc,(struct sockaddr*)addr,sizeof(addr))==SOCKET_ERROR)
fprintf(stderr,"bind error:%d\n",WSAGetLastError()); |
EndPoint point = new IPEndPoint(IPAddress.Any, ポート);
ssoc.Bind(point); |
if(listen(ssoc,バックログ数)<0) perror("listen error"); |
if(listen(ssoc,バックログ数)==SOCKET_ERROR) fprintf(stderr,"listen error:%d\n",WSAGetLastError()); |
if(!ssoc.Listen(バックログ数)) TRACE("Listen error:%d\n",
ssoc.GetLastError()); |
ssoc.Listen(バックログ数); |
オプション |
int val=1;
if(setsockopt(ssoc, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))<0)
perror("setsockopt error"); |
int val=1;
if(setsockopt(ssoc, SOL_SOCKET, SO_REUSEADDR, &val,
sizeof(val))==SOCKET_ERROR) fprintf(stderr,"setsockopt
error:%d\n",WSAGetLastError()); |
BOOL val=TRUE;
if(!ssoc.SetSockOpt(SO_REUSEADDR, &val, sizeof(val), SOL_SOCKET))
TRACE("SetSockOpt error:%d\n", ssoc.GetLastError()); |
ssoc.setReuseAddress(true); |
soc.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReuseAddress, true); |
受付タイムアウト |
fd_set mask;FD_ZERO(&mask);FD_SET(ssoc,&mask);
struct timeval tv={ タイムアウト時間[秒],[μ秒] };
int rc=select(ssoc+1,&mask,NULL,NULL,&tv);
if(rc<0) perror("accept-select error");
if(rc==0){ タイムアウト処理 } |
fd_set mask;FD_ZERO(&mask);FD_SET(ssoc,&mask);
struct timeval tv={ タイムアウト時間[秒],[μ秒] };
int rc=select((int)ssoc+1, &mask, NULL, NULL, &tv);
if(rc==SOCKET_ERROR) fprintf(stderr,"accept-select error:%d\n",WSAGetLastError());
if(rc==0){ タイムアウト処理 } |
|
ssoc.setSoTimeout(タイムアウト時間);
accept()でタイムアウトするとSocketTimeoutExceptionが発生する |
|
受付 |
for(;;){
int soc=accept(ssoc, NULL, NULL);
if(soc<0) perror("accept error");
//通信処理
} |
for(;;){
int soc=accept(ssoc, NULL, NULL);
if(soc==INVALID_SOCKET) fprintf(stderr,"accept error:%d\n",WSAGetLastError());
//通信処理
} |
CServerSocketでOnAccept()をオーバーライドしておく。通信が受け付けられるとOnAccept()が呼ばれるので、複数の通信を処理する為のループは必要ない。
void CServerSocket::OnAccept(int nErrorCode)
{
CSocket soc; //接続ソケット
if(!Accept(soc)){
TRACE("Accept error:%d\n", this->GetLastError());
return;
}
CSocketFile file(&soc, FALSE);
//通信処理
} |
for(;;) {
Socket soc = ssoc.accept();
//通信処理
} |
while(true) {
Socket soc = ssoc.Accept();
//通信処理
} |
TCPクライアント
接続 |
int soc=socket(AF_INET, SOCK_STREAM, 0);
if(soc<0) perror("socket error");
//ノンブロックに変更
int flag=fcntl(soc, F_GETFL, 0);
if(flag<0) perror("fcntl(GET) error");
if(fcntl(soc, F_SETFL, flag|O_NONBLOCK)<0) perror("fcntl(NONBLOCK)
error");
struct sockaddr_in addr={AF_INET};
addr.sin_addr.s_addr=inet_aton("IPアドレス");
addr.sin_port=htons(ポート);
if(connect(soc, (struct sockaddr*)&addr, sizeof(addr))<0){
if(errno!=EINPROGRESS) perror("connect error");
//EINPROGRESS:コネクション要求は始まったが、まだ完了していない
fd_set rmask,wmask;FD_ZERO(&rmask);FD_SET(soc,&rmask);wmask=rmask;
struct timeval tv={ タイムアウト時間[秒],[μ秒] };
int rc=select(soc+1, &rmask, &wmask, NULL, &tv);
if(rc<0) perror("connect-select error");
if(rc==0){ タイムアウト処理 }
if(rc==2){ //読み書きが同時に出来る場合
#if Solaris
int val;
socklen_t len=sizeof(val);
if(getsockopt(soc,SOL_SOCKET,SO_ERROR, &val,&len)>=0) {
#elif Linux
struct sockaddr_in name;
socklen_t len=sizeof(name);
if(getpeername(soc,(struct sockaddr*)&name,&len)>=0) {
#endif
// 既にデータが来ている
}else{
// コネクト失敗
}
}
}
//フラグを元に戻す
if(fcntl(soc, F_SETFL, flag)<0) perror("fcntl(END) error"); |
SOCKET soc=socket(AF_INET, SOCK_STREAM, 0);
if(soc==INVALID_SOCKET) fprintf(stderr,"socket
error:%d\n",WSAGetLastError());
//ノンブロックに変更
u_long flag=1;
if(ioctlsocket(soc, FIONBIO, &flag)==SOCKET_ERROR)
fprintf(stderr,"ioctl(NONBLOCK) error:%d",WSAGetLastError());
struct sockaddr_in addr={AF_INET};
addr.sin_addr.s_addr=inet_addr("IPアドレス");
addr.sin_port=htons(ポート);
if(connect(soc, (struct sockaddr*)&addr, sizeof(addr))==SOCKET_ERROR){
int errno=WSAGetLastError();
if(errno!=WSAEWOULDBLOCK) fprintf(stderr,"connect error:%d\n",errno);
fd_set rmask,wmask;FD_ZERO(&rmask);FD_SET(soc,&rmask);wmask=rmask;
struct timeval tv={ タイムアウト時間[秒],[μ秒] };
int rc=select((int)soc+1, &rmask, &wmask, NULL, &tv);
if(rc==SOCKET_ERROR) fprintf(stderr,"connect-select
error:%d\n",WSAGetLastError());
if(rc==0){ タイムアウト処理 }
if(rc==2){ //読み書きが同時に出来る場合
int val;
int len=sizeof(val);
if(getsockopt(soc,SOL_SOCKET,SO_ERROR,(char*)&val,&len)!=0) {
// 既にデータが来ている
}else{
// コネクト失敗
}
}
}
//ブロックモードにする
flag=0;
if(ioctlsocket(soc, FIONBIO, &flag)==SOCKET_ERROR)
fprintf(stderr,"ioctl(BLOCK) error:%d",WSAGetLastError()); |
CSocket soc;
if(!soc.Create(0, SOCK_STREAM))
TRACE("Create error:%d\n", soc.GetLastError());
if(!soc.Connect("IPアドレス",ポート))
TRACE("Connect error:%d\n", soc.GetLastError());
CSocketFile file(&soc, FALSE); |
SocketAddress addr = new
InetSocketAddress("IPアドレス",ポート);
Socket soc = new Socket();
soc.connect(addr, タイムアウト時間); |
IPAddress addr = IPAddress.Parse("IPアドレス");
EndPoint point = new IPEndPoint(addr, ポート);
Socket soc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
soc.Connect(point); |
ホスト名 |
struct hostent *ent=gethostbyname("ホスト"); |
struct hostent *ent=gethostbyname("ホスト"); |
soc.Connect("ホスト",ポート) |
SocketAddress addr = new InetSocketAddress("ホスト",ポート); |
IPAddress addr = Dns.Resolve("ホスト").AddressList[0]; |
待ち |
fd_set mask;FD_ZERO(&mask);FD_SET(soc,&mask);
struct timeval tv={ タイムアウト時間[秒],[μ秒] };
int rc=select(soc+1, &mask, NULL, NULL, &tv); //受信の場合
int rc=select(soc+1, NULL, &mask, NULL, &tv); //送信の場合
if(rc<0) perror("select error");
if(rc==0){ タイムアウト処理 } |
fd_set mask;FD_ZERO(&mask);FD_SET(soc,&mask);
struct timeval tv={ タイムアウト時間[秒],[μ秒] };
int rc=select((int)soc+1, &mask, NULL, NULL, &tv); //受信の場合
int rc=select((int)soc+1, NULL, &mask, NULL, &tv); //送信の場合
if(rc==SOCKET_ERROR) fprintf(stderr,"select error:%d\n",WSAGetLastError());
if(rc==0){ タイムアウト処理 } |
|
soc.setSoTimeout(タイムアウト時間);
read()でタイムアウトするとSocketTimeoutExceptionが発生する |
soc.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ReceiveTimeout , タイムアウト時間); //受信の場合
soc.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.SendTimeout, タイムアウト時間); //送信の場合 |
//受信の場合
if(!soc.Poll(タイムアウト時間, SelectMode.SelectRead))
{
タイムアウト処理
}
//送信の場合
if(!soc.Poll(タイムアウト時間, SelectMode.SelectWrite))
{
タイムアウト処理
} |
送信 |
int slen=send(soc,バッファ,送信サイズ,0);
if(slen<0) perror("send error"); |
int slen=send(soc,バッファ,送信サイズ,0);
if(slen==SOCKET_ERROR) fprintf(stderr,"send error:%d\n",WSAGetLastError()); |
file.Write(バッファ,送信サイズ); |
OutputStream os = soc.getOutputStream();
os.write(バッファ,0,送信サイズ); |
int slen = soc.Send(バッファ,送信サイズ, SocketFlags.NONE); |
受信 |
int rlen=recv(soc,バッファ,バッファサイズ,0);
if(rlen<0) perror("recv error"); |
int rlen=recv(soc,バッファ,バッファサイズ,0);
if(rlen==SOCKET_ERROR) fprintf(stderr,"recv error:%d\n",WSAGetLastError()); |
UINT rlen=file.Read(バッファ,バッファサイズ); |
InputStream is = soc.getInputStream();
int rlen = is.read(バッファ); |
int rlen = soc.Receive(バッファ); |
情報取得 |
struct sockaddr_in addr={0};
int len=sizeof(addr);
if(getsockname(soc, &addr, &len)<0) perror("getsockname error");
char *name=inet_ntoa(addr.sin_addr);
int port=ntohs(addr.sin_port); |
struct sockaddr_in addr={0};
int len=sizeof(addr);
if(getsockname(soc, &addr, &len)==SOCKET_ERROR)
fprintf(stderr,"getsockname error:%d\n",WSAGetLastError());
char *name=inet_ntoa(addr.sin_addr);
int port=ntohs(addr.sin_port); |
CString name;
UINT port;
soc.GetPeerName(name, port); |
InetAddress addr = soc. getInetAddress();
String name = addr.getHostAddress();
int port = soc.getPort(); |
IPEndPoint (IPEndPoint)point = soc.RemoteEndPoint();
string name = point.Address.ToString();
int port = point.Port; |
切断 |
shutdown(soc,種類);
SHUT_RD, SHUT_WR, SHUT_RDWR |
shutdown(soc,種類);
SD_RECEIVE, SD_SEND, SD_BOTH |
soc.ShutDown(種類);
receives, sends, both |
soc.shutdownInput();
soc.shutdownOutput(); |
soc.Shutdown(種類);
SocketShutdown.Receive, Send, Both |
クローズ |
close(soc);
close(ssoc); |
closesocket(soc);
closesocket(ssoc); |
file.Close();soc.Close();
ssoc.Close(); |
os.close();is.close();soc.close();
ssoc.close(); |
soc.Close();
ssoc.Close(); |