| | | | | | |
|---|
| ヘッダー | #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); intport=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); intport=ntohs(addr.sin_port); | CStringname; UINT port; soc.GetPeerName(name,port); | InetAddress addr = soc. getInetAddress(); Stringname = addr.getHostAddress(); intport = soc.getPort(); | IPEndPoint (IPEndPoint)point = soc.RemoteEndPoint(); stringname = point.Address.ToString(); intport = 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(); |
|---|